Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
MintableERC721Predicate
Compiler Version
v0.6.6+commit.6c089d02
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-03-12 */ // File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); } // File: @openzeppelin/contracts/utils/EnumerableSet.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256` * (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(value))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(value))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(value))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } // File: @openzeppelin/contracts/utils/Address.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.2; /** * @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 Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts/GSN/Context.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.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. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin/contracts/access/AccessControl.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context { using EnumerableSet for EnumerableSet.AddressSet; using Address for address; struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { emit RoleAdminChanged(role, _roles[role].adminRole, adminRole); _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } } // File: contracts/common/AccessControlMixin.sol pragma solidity 0.6.6; contract AccessControlMixin is AccessControl { string private _revertMsg; function _setupContractId(string memory contractId) internal { _revertMsg = string(abi.encodePacked(contractId, ": INSUFFICIENT_PERMISSIONS")); } modifier only(bytes32 role) { require( hasRole(role, _msgSender()), _revertMsg ); _; } } // File: contracts/lib/RLPReader.sol /* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns * https://github.com/hamdiallam/Solidity-RLP/blob/e681e25a376dbd5426b509380bc03446f05d0f97/contracts/RLPReader.sol */ pragma solidity 0.6.6; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint256 len; uint256 memPtr; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { require(item.length > 0, "RLPReader: INVALID_BYTES_LENGTH"); uint256 memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @param item RLP encoded list in bytes */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item), "RLPReader: ITEM_NOT_LIST"); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 listLength = _itemLength(item.memPtr); require(listLength == item.len, "RLPReader: LIST_DECODED_LENGTH_MISMATCH"); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { uint8 byte0; uint256 memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); uint256 ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } function toAddress(RLPItem memory item) internal pure returns (address) { require(!isList(item), "RLPReader: DECODING_LIST_AS_ADDRESS"); // 1 byte for the length prefix require(item.len == 21, "RLPReader: INVALID_ADDRESS_LENGTH"); return address(toUint(item)); } function toUint(RLPItem memory item) internal pure returns (uint256) { require(!isList(item), "RLPReader: DECODING_LIST_AS_UINT"); require(item.len <= 33, "RLPReader: INVALID_UINT_LENGTH"); uint256 itemLength = _itemLength(item.memPtr); require(itemLength == item.len, "RLPReader: UINT_DECODED_LENGTH_MISMATCH"); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; uint256 result; uint256 memPtr = item.memPtr + offset; assembly { result := mload(memPtr) // shfit to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint256) { uint256 itemLength = _itemLength(item.memPtr); require(itemLength == item.len, "RLPReader: UINT_STRICT_DECODED_LENGTH_MISMATCH"); // one byte prefix require(item.len == 33, "RLPReader: INVALID_UINT_STRICT_LENGTH"); uint256 result; uint256 memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { uint256 listLength = _itemLength(item.memPtr); require(listLength == item.len, "RLPReader: BYTES_DECODED_LENGTH_MISMATCH"); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; // data length bytes memory result = new bytes(len); uint256 destPtr; assembly { destPtr := add(0x20, result) } copy(item.memPtr + offset, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint256) { // add `isList` check if `item` is expected to be passsed without a check from calling function // require(isList(item), "RLPReader: NUM_ITEMS_NOT_LIST"); uint256 count = 0; uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item require(currPtr <= endPtr, "RLPReader: NUM_ITEMS_DECODED_LENGTH_MISMATCH"); count++; } return count; } // @return entire rlp item byte length function _itemLength(uint256 memPtr) private pure returns (uint256) { uint256 itemLen; uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) itemLen = 1; else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1; else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint256 memPtr) private pure returns (uint256) { uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) return 0; else if ( byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START) ) return 1; else if (byte0 < LIST_SHORT_START) // being explicit return byte0 - (STRING_LONG_START - 1) + 1; else return byte0 - (LIST_LONG_START - 1) + 1; } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy( uint256 src, uint256 dest, uint256 len ) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } } // File: @openzeppelin/contracts/introspection/IERC165.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin/contracts/token/ERC721/IERC721.sol // SPDX-License-Identifier: MIT pragma solidity ^0.6.2; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transfered from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; } // File: contracts/root/RootToken/IMintableERC721.sol pragma solidity 0.6.6; interface IMintableERC721 is IERC721 { /** * @notice called by predicate contract to mint tokens while withdrawing * @dev Should be callable only by MintableERC721Predicate * Make sure minting is done only by this function * @param user user address for whom token is being minted * @param tokenId tokenId being minted */ function mint(address user, uint256 tokenId) external; /** * @notice called by predicate contract to mint tokens while withdrawing with metadata from L2 * @dev Should be callable only by MintableERC721Predicate * Make sure minting is only done either by this function/ 👆 * @param user user address for whom token is being minted * @param tokenId tokenId being minted * @param metaData Associated token metadata, to be decoded & set using `setTokenMetadata` * * Note : If you're interested in taking token metadata from L2 to L1 during exit, you must * implement this method */ function mint(address user, uint256 tokenId, bytes calldata metaData) external; /** * @notice check if token already exists, return true if it does exist * @dev this check will be used by the predicate to determine if the token needs to be minted or transfered * @param tokenId tokenId being checked */ function exists(uint256 tokenId) external view returns (bool); } // File: contracts/root/TokenPredicates/ITokenPredicate.sol pragma solidity 0.6.6; /// @title Token predicate interface for all pos portal predicates /// @notice Abstract interface that defines methods for custom predicates interface ITokenPredicate { /** * @notice Deposit tokens into pos portal * @dev When `depositor` deposits tokens into pos portal, tokens get locked into predicate contract. * @param depositor Address who wants to deposit tokens * @param depositReceiver Address (address) who wants to receive tokens on side chain * @param rootToken Token which gets deposited * @param depositData Extra data for deposit (amount for ERC20, token id for ERC721 etc.) [ABI encoded] */ function lockTokens( address depositor, address depositReceiver, address rootToken, bytes calldata depositData ) external; /** * @notice Validates and processes exit while withdraw process * @dev Validates exit log emitted on sidechain. Reverts if validation fails. * @dev Processes withdraw based on custom logic. Example: transfer ERC20/ERC721, mint ERC721 if mintable withdraw * @param sender Address * @param rootToken Token which gets withdrawn * @param logRLPList Valid sidechain log for data like amount, token id etc. */ function exitTokens( address sender, address rootToken, bytes calldata logRLPList ) external; } // File: contracts/common/Initializable.sol pragma solidity 0.6.6; contract Initializable { bool inited = false; modifier initializer() { require(!inited, "already inited"); _; inited = true; } } // File: contracts/root/TokenPredicates/MintableERC721Predicate.sol pragma solidity 0.6.6; contract MintableERC721Predicate is ITokenPredicate, AccessControlMixin, Initializable, IERC721Receiver { using RLPReader for bytes; using RLPReader for RLPReader.RLPItem; // keccak256("MANAGER_ROLE") bytes32 public constant MANAGER_ROLE = 0x241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08; // keccak256("MintableERC721") bytes32 public constant TOKEN_TYPE = 0xd4392723c111fcb98b073fe55873efb447bcd23cd3e49ec9ea2581930cd01ddc; // keccak256("Transfer(address,address,uint256)") bytes32 public constant TRANSFER_EVENT_SIG = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef; // keccak256("WithdrawnBatch(address,uint256[])") bytes32 public constant WITHDRAW_BATCH_EVENT_SIG = 0xf871896b17e9cb7a64941c62c188a4f5c621b86800e3d15452ece01ce56073df; // keccak256("TransferWithMetadata(address,address,uint256,bytes)") bytes32 public constant TRANSFER_WITH_METADATA_EVENT_SIG = 0xf94915c6d1fd521cee85359239227480c7e8776d7caf1fc3bacad5c269b66a14; // limit batching of tokens due to gas limit restrictions uint256 public constant BATCH_LIMIT = 20; event LockedMintableERC721( address indexed depositor, address indexed depositReceiver, address indexed rootToken, uint256 tokenId ); event LockedMintableERC721Batch( address indexed depositor, address indexed depositReceiver, address indexed rootToken, uint256[] tokenIds ); constructor() public {} function initialize(address _owner) external initializer { _setupContractId("MintableERC721Predicate"); _setupRole(DEFAULT_ADMIN_ROLE, _owner); _setupRole(MANAGER_ROLE, _owner); } /** * @notice accepts safe ERC721 transfer */ function onERC721Received( address, address, uint256, bytes calldata ) external override returns (bytes4) { return IERC721Receiver.onERC721Received.selector; } /** * @notice Lock ERC721 token(s) for deposit, callable only by manager * @param depositor Address who wants to deposit token * @param depositReceiver Address (address) who wants to receive token on child chain * @param rootToken Token which gets deposited * @param depositData ABI encoded tokenId(s). It's possible to deposit batch of tokens. */ function lockTokens( address depositor, address depositReceiver, address rootToken, bytes calldata depositData ) external override only(MANAGER_ROLE) { // Locking single ERC721 token if (depositData.length == 32) { uint256 tokenId = abi.decode(depositData, (uint256)); // Emitting event that single token is getting locked in predicate emit LockedMintableERC721(depositor, depositReceiver, rootToken, tokenId); // Transferring token to this address, which will be // released when attempted to be unlocked IMintableERC721(rootToken).safeTransferFrom(depositor, address(this), tokenId); } else { // Locking a set a ERC721 token(s) uint256[] memory tokenIds = abi.decode(depositData, (uint256[])); // Emitting event that a set of ERC721 tokens are getting lockec // in this predicate contract emit LockedMintableERC721Batch(depositor, depositReceiver, rootToken, tokenIds); // These many tokens are attempted to be deposited // by user uint256 length = tokenIds.length; require(length <= BATCH_LIMIT, "MintableERC721Predicate: EXCEEDS_BATCH_LIMIT"); // Iteratively trying to transfer ERC721 token // to this predicate address for (uint256 i; i < length; i++) { IMintableERC721(rootToken).safeTransferFrom(depositor, address(this), tokenIds[i]); } } } /** * @notice Validates log signature, from and to address * then checks if token already exists on root chain * if token exits then transfers it to withdrawer * if token doesn't exit then it is minted * callable only by manager * @param rootToken Token which gets withdrawn * @param log Valid ERC721 burn log from child chain */ function exitTokens( address, address rootToken, bytes memory log ) public override only(MANAGER_ROLE) { RLPReader.RLPItem[] memory logRLPList = log.toRlpItem().toList(); RLPReader.RLPItem[] memory logTopicRLPList = logRLPList[1].toList(); // topics // If it's a simple exit ( with out metadata coming from L2 to L1 ) if(bytes32(logTopicRLPList[0].toUint()) == TRANSFER_EVENT_SIG) { address withdrawer = address(logTopicRLPList[1].toUint()); // topic1 is from address require( address(logTopicRLPList[2].toUint()) == address(0), // topic2 is to address "MintableERC721Predicate: INVALID_RECEIVER" ); IMintableERC721 token = IMintableERC721(rootToken); uint256 tokenId = logTopicRLPList[3].toUint(); // topic3 is tokenId field if (token.exists(tokenId)) { token.safeTransferFrom( address(this), withdrawer, tokenId ); } else { token.mint(withdrawer, tokenId); } } else if (bytes32(logTopicRLPList[0].toUint()) == WITHDRAW_BATCH_EVENT_SIG) { // topic0 is event sig // If it's a simple batch exit, where a set of // ERC721s were burnt in child chain with event signature // looking like `WithdrawnBatch(address indexed user, uint256[] tokenIds);` // // @note This doesn't allow transfer of metadata cross chain // For that check below `else if` block address withdrawer = address(logTopicRLPList[1].toUint()); // topic1 is from address // RLP encoded tokenId list bytes memory logData = logRLPList[2].toBytes(); (uint256[] memory tokenIds) = abi.decode(logData, (uint256[])); uint256 length = tokenIds.length; IMintableERC721 token = IMintableERC721(rootToken); for (uint256 i; i < length; i++) { uint256 tokenId = tokenIds[i]; // Check if token exists or not // // If does, transfer token to withdrawer if (token.exists(tokenId)) { token.safeTransferFrom( address(this), withdrawer, tokenId ); } else { // If token was minted on L2 // we'll mint it here, on L1, during // exiting from L2 token.mint(withdrawer, tokenId); } } } else if (bytes32(logTopicRLPList[0].toUint()) == TRANSFER_WITH_METADATA_EVENT_SIG) { // If this is NFT exit with metadata i.e. URI 👆 // // Note: If your token is only minted in L2, you can exit // it with metadata. But if it was minted on L1, it'll be // simply transferred to withdrawer address. And in that case, // it's lot better to exit with `Transfer(address,address,uint256)` // i.e. calling `withdraw` method on L2 contract // event signature proof, which is defined under first `if` clause // // If you've called `withdrawWithMetadata`, you should submit // proof of event signature `TransferWithMetadata(address,address,uint256,bytes)` address withdrawer = address(logTopicRLPList[1].toUint()); // topic1 is from address require( address(logTopicRLPList[2].toUint()) == address(0), // topic2 is to address "MintableERC721Predicate: INVALID_RECEIVER" ); IMintableERC721 token = IMintableERC721(rootToken); uint256 tokenId = logTopicRLPList[3].toUint(); // topic3 is tokenId field if (token.exists(tokenId)) { token.safeTransferFrom( address(this), withdrawer, tokenId ); } else { // Minting with metadata received from L2 i.e. emitted // by event `TransferWithMetadata` during burning token.mint(withdrawer, tokenId, logRLPList[2].toBytes()); } } else { // Attempting to exit with some event signature from L2, which is // not ( yet ) supported by L1 exit manager revert("MintableERC721Predicate: INVALID_SIGNATURE"); } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":true,"internalType":"address","name":"depositReceiver","type":"address"},{"indexed":true,"internalType":"address","name":"rootToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"LockedMintableERC721","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":true,"internalType":"address","name":"depositReceiver","type":"address"},{"indexed":true,"internalType":"address","name":"rootToken","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"LockedMintableERC721Batch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"BATCH_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSFER_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSFER_WITH_METADATA_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WITHDRAW_BATCH_EVENT_SIG","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"rootToken","type":"address"},{"internalType":"bytes","name":"log","type":"bytes"}],"name":"exitTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"},{"internalType":"address","name":"depositReceiver","type":"address"},{"internalType":"address","name":"rootToken","type":"address"},{"internalType":"bytes","name":"depositData","type":"bytes"}],"name":"lockTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526002805460ff1916905534801561001a57600080fd5b506120588061002a6000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c806391d14854116100a2578063c4d66de811610071578063c4d66de8146103bb578063ca15c873146103e1578063d547741f146103fe578063e375b64e1461042a578063ec87621c146104b957610116565b806391d14854146103635780639559c0bd146103a3578063a217fddf146103ab578063b017a30f146103b357610116565b80634794b430116100e95780634794b4301461024f57806349f5124b14610257578063609c92b81461025f5780638274664f146102675780639010d07c1461032457610116565b8063150b7a021461011b578063248a9ca3146101c65780632f2ff15d146101f557806336568abe14610223575b600080fd5b6101a96004803603608081101561013157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561016b57600080fd5b82018360208201111561017d57600080fd5b803590602001918460018302840111600160201b8311171561019e57600080fd5b5090925090506104c1565b604080516001600160e01b03199092168252519081900360200190f35b6101e3600480360360208110156101dc57600080fd5b50356104d2565b60408051918252519081900360200190f35b6102216004803603604081101561020b57600080fd5b50803590602001356001600160a01b03166104ea565b005b6102216004803603604081101561023957600080fd5b50803590602001356001600160a01b0316610556565b6101e36105b7565b6101e36105db565b6101e36105ff565b6102216004803603606081101561027d57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b8111156102b057600080fd5b8201836020820111156102c257600080fd5b803590602001918460018302840111600160201b831117156102e357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610623945050505050565b6103476004803603604081101561033a57600080fd5b5080359060200135610eb4565b604080516001600160a01b039092168252519081900360200190f35b61038f6004803603604081101561037957600080fd5b50803590602001356001600160a01b0316610edb565b604080519115158252519081900360200190f35b6101e3610ef9565b6101e3610efe565b6101e3610f03565b610221600480360360208110156103d157600080fd5b50356001600160a01b0316610f27565b6101e3600480360360208110156103f757600080fd5b5035610fe1565b6102216004803603604081101561041457600080fd5b50803590602001356001600160a01b0316610ff8565b6102216004803603608081101561044057600080fd5b6001600160a01b0382358116926020810135821692604082013590921691810190608081016060820135600160201b81111561047b57600080fd5b82018360208201111561048d57600080fd5b803590602001918460018302840111600160201b831117156104ae57600080fd5b509092509050611051565b6101e36113f8565b630a85bd0160e11b95945050505050565b6000818152602081905260409020600201545b919050565b60008281526020819052604090206002015461050d9061050861140a565b610edb565b6105485760405162461bcd60e51b815260040180806020018281038252602f815260200180611e54602f913960400191505060405180910390fd5b610552828261140f565b5050565b61055e61140a565b6001600160a01b0316816001600160a01b0316146105ad5760405162461bcd60e51b815260040180806020018281038252602f815260200180611fcd602f913960400191505060405180910390fd5b610552828261147e565b7ff871896b17e9cb7a64941c62c188a4f5c621b86800e3d15452ece01ce56073df81565b7ff94915c6d1fd521cee85359239227480c7e8776d7caf1fc3bacad5c269b66a1481565b7fd4392723c111fcb98b073fe55873efb447bcd23cd3e49ec9ea2581930cd01ddc81565b600080516020611f5d83398151915261063e8161050861140a565b6001906106de5760405162461bcd60e51b81526020600482019081528254600260001961010060018416150201909116046024830181905290918291604490910190849080156106cf5780601f106106a4576101008083540402835291602001916106cf565b820191906000526020600020905b8154815290600101906020018083116106b257829003601f168201915b50509250505060405180910390fd5b5060606106f26106ed846114ed565b611568565b905060606107138260018151811061070657fe5b6020026020010151611568565b90507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60001b6107568260008151811061074957fe5b60200260200101516116ea565b141561095457600061076e8260018151811061074957fe5b905060006001600160a01b031661078b8360028151811061074957fe5b6001600160a01b0316146107d05760405162461bcd60e51b8152600401808060200182810382526029815260200180611f7d6029913960400191505060405180910390fd5b600086905060006107e78460038151811061074957fe5b9050816001600160a01b0316634f558e79826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561082d57600080fd5b505afa158015610841573d6000803e3d6000fd5b505050506040513d602081101561085757600080fd5b5051156108d35760408051632142170760e11b81523060048201526001600160a01b038581166024830152604482018490529151918416916342842e0e9160648082019260009290919082900301818387803b1580156108b657600080fd5b505af11580156108ca573d6000803e3d6000fd5b5050505061094c565b816001600160a01b03166340c10f1984836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561093357600080fd5b505af1158015610947573d6000803e3d6000fd5b505050505b505050610eac565b7ff871896b17e9cb7a64941c62c188a4f5c621b86800e3d15452ece01ce56073df60001b6109888260008151811061074957fe5b1415610c085760006109a08260018151811061074957fe5b905060606109c1846002815181106109b457fe5b6020026020010151611832565b905060608180602001905160208110156109da57600080fd5b8101908080516040519392919084600160201b8211156109f957600080fd5b908301906020820185811115610a0e57600080fd5b82518660208202830111600160201b82111715610a2a57600080fd5b82525081516020918201928201910280838360005b83811015610a57578181015183820152602001610a3f565b5050505091909101604052505082519293508a9150600090505b82811015610bfd576000848281518110610a8757fe5b60200260200101519050826001600160a01b0316634f558e79826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610ad557600080fd5b505afa158015610ae9573d6000803e3d6000fd5b505050506040513d6020811015610aff57600080fd5b505115610b7b5760408051632142170760e11b81523060048201526001600160a01b038981166024830152604482018490529151918516916342842e0e9160648082019260009290919082900301818387803b158015610b5e57600080fd5b505af1158015610b72573d6000803e3d6000fd5b50505050610bf4565b826001600160a01b03166340c10f1988836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610bdb57600080fd5b505af1158015610bef573d6000803e3d6000fd5b505050505b50600101610a71565b505050505050610eac565b7ff94915c6d1fd521cee85359239227480c7e8776d7caf1fc3bacad5c269b66a1460001b610c3c8260008151811061074957fe5b1415610e75576000610c548260018151811061074957fe5b905060006001600160a01b0316610c718360028151811061074957fe5b6001600160a01b031614610cb65760405162461bcd60e51b8152600401808060200182810382526029815260200180611f7d6029913960400191505060405180910390fd5b60008690506000610ccd8460038151811061074957fe5b9050816001600160a01b0316634f558e79826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610d1357600080fd5b505afa158015610d27573d6000803e3d6000fd5b505050506040513d6020811015610d3d57600080fd5b505115610d9c5760408051632142170760e11b81523060048201526001600160a01b038581166024830152604482018490529151918416916342842e0e9160648082019260009290919082900301818387803b1580156108b657600080fd5b816001600160a01b03166394d008ef8483610dbd896002815181106109b457fe5b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610e27578181015183820152602001610e0f565b50505050905090810190601f168015610e545780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561093357600080fd5b60405162461bcd60e51b815260040180806020018281038252602a815260200180611e83602a913960400191505060405180910390fd5b505050505050565b6000828152602081905260408120610ed2908363ffffffff6118fc16565b90505b92915050565b6000828152602081905260408120610ed2908363ffffffff61190816565b601481565b600081565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef81565b60025460ff1615610f70576040805162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015290519081900360640190fd5b610fae6040518060400160405280601781526020017f4d696e7461626c6545524337323150726564696361746500000000000000000081525061191d565b610fb9600082610548565b610fd1600080516020611f5d83398151915282610548565b506002805460ff19166001179055565b6000818152602081905260408120610ed5906119bb565b6000828152602081905260409020600201546110169061050861140a565b6105ad5760405162461bcd60e51b8152600401808060200182810382526030815260200180611ed56030913960400191505060405180910390fd5b600080516020611f5d83398151915261106c8161050861140a565b6001906110d25760405162461bcd60e51b81526020600482019081528254600260001961010060018416150201909116046024830181905290918291604490910190849080156106cf5780601f106106a4576101008083540402835291602001916106cf565b5060208214156111b1576000838360208110156110ee57600080fd5b5060408051913580835290519092506001600160a01b038088169289821692918b16917fe13244aa06bdc79480ed5fdc6ebe2bb37202fcdf33ecf45dc449f4201f3dc0879181900360200190a460408051632142170760e11b81526001600160a01b038981166004830152306024830152604482018490529151918716916342842e0e9160648082019260009290919082900301818387803b15801561119357600080fd5b505af11580156111a7573d6000803e3d6000fd5b5050505050610eac565b6060838360208110156111c357600080fd5b810190602081018135600160201b8111156111dd57600080fd5b8201836020820111156111ef57600080fd5b803590602001918460208302840111600160201b8311171561121057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050509050846001600160a01b0316866001600160a01b0316886001600160a01b03167fdb55e3a0ae817693fd7b07170d81eab0eb2c239f36fcecbc98b6b58ac5667e7a846040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156112dc5781810151838201526020016112c4565b505050509050019250505060405180910390a4805160148111156113315760405162461bcd60e51b815260040180806020018281038252602c815260200180611f31602c913960400191505060405180910390fd5b60005b818110156113ed57866001600160a01b03166342842e0e8a3086858151811061135957fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b1580156113c957600080fd5b505af11580156113dd573d6000803e3d6000fd5b5050600190920191506113349050565b505050505050505050565b600080516020611f5d83398151915281565b335b90565b600082815260208190526040902061142d908263ffffffff6119c616565b156105525761143a61140a565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260208190526040902061149c908263ffffffff6119db16565b15610552576114a961140a565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6114f5611d7f565b600082511161154b576040805162461bcd60e51b815260206004820152601f60248201527f524c505265616465723a20494e56414c49445f42595445535f4c454e47544800604482015290519081900360640190fd5b506040805180820190915281518152602082810190820152919050565b6060611573826119f0565b6115c4576040805162461bcd60e51b815260206004820152601860248201527f524c505265616465723a204954454d5f4e4f545f4c4953540000000000000000604482015290519081900360640190fd5b60006115cf83611a1c565b905060608167ffffffffffffffff811180156115ea57600080fd5b5060405190808252806020026020018201604052801561162457816020015b611611611d7f565b8152602001906001900390816116095790505b50905060006116368560200151611aa8565b855190915081146116785760405162461bcd60e51b8152600401808060200182810382526027815260200180611fa66027913960400191505060405180910390fd5b60006116878660200151611b41565b60208701510190506000805b858110156116de576116a483611aa8565b91506040518060400160405280838152602001848152508582815181106116c757fe5b602090810291909101015291810191600101611693565b50929695505050505050565b60006116f5826119f0565b15611747576040805162461bcd60e51b815260206004820181905260248201527f524c505265616465723a204445434f44494e475f4c4953545f41535f55494e54604482015290519081900360640190fd5b81516021101561179e576040805162461bcd60e51b815260206004820152601e60248201527f524c505265616465723a20494e56414c49445f55494e545f4c454e4754480000604482015290519081900360640190fd5b60006117ad8360200151611aa8565b835190915081146117ef5760405162461bcd60e51b8152600401808060200182810382526027815260200180611ffc6027913960400191505060405180910390fd5b60006117fe8460200151611b41565b8451602080870151830180519394509184900392919083101561182857826020036101000a820491505b5095945050505050565b606060006118438360200151611aa8565b835190915081146118855760405162461bcd60e51b8152600401808060200182810382526028815260200180611ead6028913960400191505060405180910390fd5b60006118948460200151611b41565b845190915081900360608167ffffffffffffffff811180156118b557600080fd5b506040519080825280601f01601f1916602001820160405280156118e0576020820181803683370190505b5090506000816020019050611828848860200151018285611ba4565b6000610ed28383611bef565b6000610ed2836001600160a01b038416611c53565b806040516020018082805190602001908083835b602083106119505780518252601f199092019160209182019101611931565b51815160209384036101000a60001901801990921691161790527f3a20494e53554646494349454e545f5045524d495353494f4e530000000000009190930190815260408051808303600519018152601a909201905280516105529550600194509201919050611d99565b6000610ed582611c6b565b6000610ed2836001600160a01b038416611c6f565b6000610ed2836001600160a01b038416611cb9565b6020810151805160009190821a9060c0821015611a12576000925050506104e5565b5060019392505050565b600080600090506000611a328460200151611b41565b602085015185519181019250015b80821015611a9f57611a5182611aa8565b8201915080821115611a945760405162461bcd60e51b815260040180806020018281038252602c815260200180611f05602c913960400191505060405180910390fd5b600190920191611a40565b50909392505050565b80516000908190811a6080811015611ac35760019150611b3a565b60b8811015611ad857607e1981019150611b3a565b60c0811015611b055760b78103600185019450806020036101000a85510460018201810193505050611b3a565b60f8811015611b1a5760be1981019150611b3a565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b8051600090811a6080811015611b5b5760009150506104e5565b60b8811080611b76575060c08110801590611b76575060f881105b15611b855760019150506104e5565b60c0811015611b995760b5190190506104e5565b60f5190190506104e5565b80611bae57611bea565b5b60208110611bce578251825260209283019290910190601f1901611baf565b8251825160208390036101000a60001901801990921691161782525b505050565b81546000908210611c315760405162461bcd60e51b8152600401808060200182810382526022815260200180611e326022913960400191505060405180910390fd5b826000018281548110611c4057fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000611c7b8383611c53565b611cb157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ed5565b506000610ed5565b60008181526001830160205260408120548015611d755783546000198083019190810190600090879083908110611cec57fe5b9060005260206000200154905080876000018481548110611d0957fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611d3957fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ed5565b6000915050610ed5565b604051806040016040528060008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611dda57805160ff1916838001178555611e07565b82800160010185558215611e07579182015b82811115611e07578251825591602001919060010190611dec565b50611e13929150611e17565b5090565b61140c91905b80821115611e135760008155600101611e1d56fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744d696e7461626c654552433732315072656469636174653a20494e56414c49445f5349474e4154555245524c505265616465723a2042595445535f4445434f4445445f4c454e4754485f4d49534d41544348416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65524c505265616465723a204e554d5f4954454d535f4445434f4445445f4c454e4754485f4d49534d415443484d696e7461626c654552433732315072656469636174653a20455843454544535f42415443485f4c494d4954241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b084d696e7461626c654552433732315072656469636174653a20494e56414c49445f5245434549564552524c505265616465723a204c4953545f4445434f4445445f4c454e4754485f4d49534d41544348416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66524c505265616465723a2055494e545f4445434f4445445f4c454e4754485f4d49534d41544348a264697066735822122055f4047592f7fc9a84a90b99abfaf361fc1c15addcb132a1678d94309ce107cf64736f6c63430006060033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101165760003560e01c806391d14854116100a2578063c4d66de811610071578063c4d66de8146103bb578063ca15c873146103e1578063d547741f146103fe578063e375b64e1461042a578063ec87621c146104b957610116565b806391d14854146103635780639559c0bd146103a3578063a217fddf146103ab578063b017a30f146103b357610116565b80634794b430116100e95780634794b4301461024f57806349f5124b14610257578063609c92b81461025f5780638274664f146102675780639010d07c1461032457610116565b8063150b7a021461011b578063248a9ca3146101c65780632f2ff15d146101f557806336568abe14610223575b600080fd5b6101a96004803603608081101561013157600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b81111561016b57600080fd5b82018360208201111561017d57600080fd5b803590602001918460018302840111600160201b8311171561019e57600080fd5b5090925090506104c1565b604080516001600160e01b03199092168252519081900360200190f35b6101e3600480360360208110156101dc57600080fd5b50356104d2565b60408051918252519081900360200190f35b6102216004803603604081101561020b57600080fd5b50803590602001356001600160a01b03166104ea565b005b6102216004803603604081101561023957600080fd5b50803590602001356001600160a01b0316610556565b6101e36105b7565b6101e36105db565b6101e36105ff565b6102216004803603606081101561027d57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b8111156102b057600080fd5b8201836020820111156102c257600080fd5b803590602001918460018302840111600160201b831117156102e357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610623945050505050565b6103476004803603604081101561033a57600080fd5b5080359060200135610eb4565b604080516001600160a01b039092168252519081900360200190f35b61038f6004803603604081101561037957600080fd5b50803590602001356001600160a01b0316610edb565b604080519115158252519081900360200190f35b6101e3610ef9565b6101e3610efe565b6101e3610f03565b610221600480360360208110156103d157600080fd5b50356001600160a01b0316610f27565b6101e3600480360360208110156103f757600080fd5b5035610fe1565b6102216004803603604081101561041457600080fd5b50803590602001356001600160a01b0316610ff8565b6102216004803603608081101561044057600080fd5b6001600160a01b0382358116926020810135821692604082013590921691810190608081016060820135600160201b81111561047b57600080fd5b82018360208201111561048d57600080fd5b803590602001918460018302840111600160201b831117156104ae57600080fd5b509092509050611051565b6101e36113f8565b630a85bd0160e11b95945050505050565b6000818152602081905260409020600201545b919050565b60008281526020819052604090206002015461050d9061050861140a565b610edb565b6105485760405162461bcd60e51b815260040180806020018281038252602f815260200180611e54602f913960400191505060405180910390fd5b610552828261140f565b5050565b61055e61140a565b6001600160a01b0316816001600160a01b0316146105ad5760405162461bcd60e51b815260040180806020018281038252602f815260200180611fcd602f913960400191505060405180910390fd5b610552828261147e565b7ff871896b17e9cb7a64941c62c188a4f5c621b86800e3d15452ece01ce56073df81565b7ff94915c6d1fd521cee85359239227480c7e8776d7caf1fc3bacad5c269b66a1481565b7fd4392723c111fcb98b073fe55873efb447bcd23cd3e49ec9ea2581930cd01ddc81565b600080516020611f5d83398151915261063e8161050861140a565b6001906106de5760405162461bcd60e51b81526020600482019081528254600260001961010060018416150201909116046024830181905290918291604490910190849080156106cf5780601f106106a4576101008083540402835291602001916106cf565b820191906000526020600020905b8154815290600101906020018083116106b257829003601f168201915b50509250505060405180910390fd5b5060606106f26106ed846114ed565b611568565b905060606107138260018151811061070657fe5b6020026020010151611568565b90507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60001b6107568260008151811061074957fe5b60200260200101516116ea565b141561095457600061076e8260018151811061074957fe5b905060006001600160a01b031661078b8360028151811061074957fe5b6001600160a01b0316146107d05760405162461bcd60e51b8152600401808060200182810382526029815260200180611f7d6029913960400191505060405180910390fd5b600086905060006107e78460038151811061074957fe5b9050816001600160a01b0316634f558e79826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561082d57600080fd5b505afa158015610841573d6000803e3d6000fd5b505050506040513d602081101561085757600080fd5b5051156108d35760408051632142170760e11b81523060048201526001600160a01b038581166024830152604482018490529151918416916342842e0e9160648082019260009290919082900301818387803b1580156108b657600080fd5b505af11580156108ca573d6000803e3d6000fd5b5050505061094c565b816001600160a01b03166340c10f1984836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561093357600080fd5b505af1158015610947573d6000803e3d6000fd5b505050505b505050610eac565b7ff871896b17e9cb7a64941c62c188a4f5c621b86800e3d15452ece01ce56073df60001b6109888260008151811061074957fe5b1415610c085760006109a08260018151811061074957fe5b905060606109c1846002815181106109b457fe5b6020026020010151611832565b905060608180602001905160208110156109da57600080fd5b8101908080516040519392919084600160201b8211156109f957600080fd5b908301906020820185811115610a0e57600080fd5b82518660208202830111600160201b82111715610a2a57600080fd5b82525081516020918201928201910280838360005b83811015610a57578181015183820152602001610a3f565b5050505091909101604052505082519293508a9150600090505b82811015610bfd576000848281518110610a8757fe5b60200260200101519050826001600160a01b0316634f558e79826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610ad557600080fd5b505afa158015610ae9573d6000803e3d6000fd5b505050506040513d6020811015610aff57600080fd5b505115610b7b5760408051632142170760e11b81523060048201526001600160a01b038981166024830152604482018490529151918516916342842e0e9160648082019260009290919082900301818387803b158015610b5e57600080fd5b505af1158015610b72573d6000803e3d6000fd5b50505050610bf4565b826001600160a01b03166340c10f1988836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015610bdb57600080fd5b505af1158015610bef573d6000803e3d6000fd5b505050505b50600101610a71565b505050505050610eac565b7ff94915c6d1fd521cee85359239227480c7e8776d7caf1fc3bacad5c269b66a1460001b610c3c8260008151811061074957fe5b1415610e75576000610c548260018151811061074957fe5b905060006001600160a01b0316610c718360028151811061074957fe5b6001600160a01b031614610cb65760405162461bcd60e51b8152600401808060200182810382526029815260200180611f7d6029913960400191505060405180910390fd5b60008690506000610ccd8460038151811061074957fe5b9050816001600160a01b0316634f558e79826040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015610d1357600080fd5b505afa158015610d27573d6000803e3d6000fd5b505050506040513d6020811015610d3d57600080fd5b505115610d9c5760408051632142170760e11b81523060048201526001600160a01b038581166024830152604482018490529151918416916342842e0e9160648082019260009290919082900301818387803b1580156108b657600080fd5b816001600160a01b03166394d008ef8483610dbd896002815181106109b457fe5b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610e27578181015183820152602001610e0f565b50505050905090810190601f168015610e545780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561093357600080fd5b60405162461bcd60e51b815260040180806020018281038252602a815260200180611e83602a913960400191505060405180910390fd5b505050505050565b6000828152602081905260408120610ed2908363ffffffff6118fc16565b90505b92915050565b6000828152602081905260408120610ed2908363ffffffff61190816565b601481565b600081565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef81565b60025460ff1615610f70576040805162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015290519081900360640190fd5b610fae6040518060400160405280601781526020017f4d696e7461626c6545524337323150726564696361746500000000000000000081525061191d565b610fb9600082610548565b610fd1600080516020611f5d83398151915282610548565b506002805460ff19166001179055565b6000818152602081905260408120610ed5906119bb565b6000828152602081905260409020600201546110169061050861140a565b6105ad5760405162461bcd60e51b8152600401808060200182810382526030815260200180611ed56030913960400191505060405180910390fd5b600080516020611f5d83398151915261106c8161050861140a565b6001906110d25760405162461bcd60e51b81526020600482019081528254600260001961010060018416150201909116046024830181905290918291604490910190849080156106cf5780601f106106a4576101008083540402835291602001916106cf565b5060208214156111b1576000838360208110156110ee57600080fd5b5060408051913580835290519092506001600160a01b038088169289821692918b16917fe13244aa06bdc79480ed5fdc6ebe2bb37202fcdf33ecf45dc449f4201f3dc0879181900360200190a460408051632142170760e11b81526001600160a01b038981166004830152306024830152604482018490529151918716916342842e0e9160648082019260009290919082900301818387803b15801561119357600080fd5b505af11580156111a7573d6000803e3d6000fd5b5050505050610eac565b6060838360208110156111c357600080fd5b810190602081018135600160201b8111156111dd57600080fd5b8201836020820111156111ef57600080fd5b803590602001918460208302840111600160201b8311171561121057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050509050846001600160a01b0316866001600160a01b0316886001600160a01b03167fdb55e3a0ae817693fd7b07170d81eab0eb2c239f36fcecbc98b6b58ac5667e7a846040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156112dc5781810151838201526020016112c4565b505050509050019250505060405180910390a4805160148111156113315760405162461bcd60e51b815260040180806020018281038252602c815260200180611f31602c913960400191505060405180910390fd5b60005b818110156113ed57866001600160a01b03166342842e0e8a3086858151811061135957fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050600060405180830381600087803b1580156113c957600080fd5b505af11580156113dd573d6000803e3d6000fd5b5050600190920191506113349050565b505050505050505050565b600080516020611f5d83398151915281565b335b90565b600082815260208190526040902061142d908263ffffffff6119c616565b156105525761143a61140a565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260208190526040902061149c908263ffffffff6119db16565b15610552576114a961140a565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6114f5611d7f565b600082511161154b576040805162461bcd60e51b815260206004820152601f60248201527f524c505265616465723a20494e56414c49445f42595445535f4c454e47544800604482015290519081900360640190fd5b506040805180820190915281518152602082810190820152919050565b6060611573826119f0565b6115c4576040805162461bcd60e51b815260206004820152601860248201527f524c505265616465723a204954454d5f4e4f545f4c4953540000000000000000604482015290519081900360640190fd5b60006115cf83611a1c565b905060608167ffffffffffffffff811180156115ea57600080fd5b5060405190808252806020026020018201604052801561162457816020015b611611611d7f565b8152602001906001900390816116095790505b50905060006116368560200151611aa8565b855190915081146116785760405162461bcd60e51b8152600401808060200182810382526027815260200180611fa66027913960400191505060405180910390fd5b60006116878660200151611b41565b60208701510190506000805b858110156116de576116a483611aa8565b91506040518060400160405280838152602001848152508582815181106116c757fe5b602090810291909101015291810191600101611693565b50929695505050505050565b60006116f5826119f0565b15611747576040805162461bcd60e51b815260206004820181905260248201527f524c505265616465723a204445434f44494e475f4c4953545f41535f55494e54604482015290519081900360640190fd5b81516021101561179e576040805162461bcd60e51b815260206004820152601e60248201527f524c505265616465723a20494e56414c49445f55494e545f4c454e4754480000604482015290519081900360640190fd5b60006117ad8360200151611aa8565b835190915081146117ef5760405162461bcd60e51b8152600401808060200182810382526027815260200180611ffc6027913960400191505060405180910390fd5b60006117fe8460200151611b41565b8451602080870151830180519394509184900392919083101561182857826020036101000a820491505b5095945050505050565b606060006118438360200151611aa8565b835190915081146118855760405162461bcd60e51b8152600401808060200182810382526028815260200180611ead6028913960400191505060405180910390fd5b60006118948460200151611b41565b845190915081900360608167ffffffffffffffff811180156118b557600080fd5b506040519080825280601f01601f1916602001820160405280156118e0576020820181803683370190505b5090506000816020019050611828848860200151018285611ba4565b6000610ed28383611bef565b6000610ed2836001600160a01b038416611c53565b806040516020018082805190602001908083835b602083106119505780518252601f199092019160209182019101611931565b51815160209384036101000a60001901801990921691161790527f3a20494e53554646494349454e545f5045524d495353494f4e530000000000009190930190815260408051808303600519018152601a909201905280516105529550600194509201919050611d99565b6000610ed582611c6b565b6000610ed2836001600160a01b038416611c6f565b6000610ed2836001600160a01b038416611cb9565b6020810151805160009190821a9060c0821015611a12576000925050506104e5565b5060019392505050565b600080600090506000611a328460200151611b41565b602085015185519181019250015b80821015611a9f57611a5182611aa8565b8201915080821115611a945760405162461bcd60e51b815260040180806020018281038252602c815260200180611f05602c913960400191505060405180910390fd5b600190920191611a40565b50909392505050565b80516000908190811a6080811015611ac35760019150611b3a565b60b8811015611ad857607e1981019150611b3a565b60c0811015611b055760b78103600185019450806020036101000a85510460018201810193505050611b3a565b60f8811015611b1a5760be1981019150611b3a565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b8051600090811a6080811015611b5b5760009150506104e5565b60b8811080611b76575060c08110801590611b76575060f881105b15611b855760019150506104e5565b60c0811015611b995760b5190190506104e5565b60f5190190506104e5565b80611bae57611bea565b5b60208110611bce578251825260209283019290910190601f1901611baf565b8251825160208390036101000a60001901801990921691161782525b505050565b81546000908210611c315760405162461bcd60e51b8152600401808060200182810382526022815260200180611e326022913960400191505060405180910390fd5b826000018281548110611c4057fe5b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b5490565b6000611c7b8383611c53565b611cb157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ed5565b506000610ed5565b60008181526001830160205260408120548015611d755783546000198083019190810190600090879083908110611cec57fe5b9060005260206000200154905080876000018481548110611d0957fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080611d3957fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ed5565b6000915050610ed5565b604051806040016040528060008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10611dda57805160ff1916838001178555611e07565b82800160010185558215611e07579182015b82811115611e07578251825591602001919060010190611dec565b50611e13929150611e17565b5090565b61140c91905b80821115611e135760008155600101611e1d56fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f206772616e744d696e7461626c654552433732315072656469636174653a20494e56414c49445f5349474e4154555245524c505265616465723a2042595445535f4445434f4445445f4c454e4754485f4d49534d41544348416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e2061646d696e20746f207265766f6b65524c505265616465723a204e554d5f4954454d535f4445434f4445445f4c454e4754485f4d49534d415443484d696e7461626c654552433732315072656469636174653a20455843454544535f42415443485f4c494d4954241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b084d696e7461626c654552433732315072656469636174653a20494e56414c49445f5245434549564552524c505265616465723a204c4953545f4445434f4445445f4c454e4754485f4d49534d41544348416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636520726f6c657320666f722073656c66524c505265616465723a2055494e545f4445434f4445445f4c454e4754485f4d49534d41544348a264697066735822122055f4047592f7fc9a84a90b99abfaf361fc1c15addcb132a1678d94309ce107cf64736f6c63430006060033
Deployed Bytecode Sourcemap
41896:9298:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;41896:9298:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;43733:246:0;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;;;;;43733:246:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;43733:246:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;43733:246:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;43733:246:0;;-1:-1:-1;43733:246:0;-1:-1:-1;43733:246:0;:::i;:::-;;;;-1:-1:-1;;;;;;43733:246:0;;;;;;;;;;;;;;20690:114;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;20690:114:0;;:::i;:::-;;;;;;;;;;;;;;;;21066:227;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;21066:227:0;;;;;;-1:-1:-1;;;;;21066:227:0;;:::i;:::-;;22275:209;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;22275:209:0;;;;;;-1:-1:-1;;;;;22275:209:0;;:::i;42605:117::-;;;:::i;42802:125::-;;;:::i;42267:103::-;;;:::i;46419:4772::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;46419:4772:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;46419:4772:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;46419:4772:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;46419:4772:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;46419:4772:0;;-1:-1:-1;46419:4772:0;;-1:-1:-1;;;;;46419:4772:0:i;20363:138::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;20363:138:0;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;20363:138:0;;;;;;;;;;;;;;19324:139;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;19324:139:0;;;;;;-1:-1:-1;;;;;19324:139:0;;:::i;:::-;;;;;;;;;;;;;;;;;;42999:40;;;:::i;18069:49::-;;;:::i;42432:111::-;;;:::i;43451:211::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;43451:211:0;-1:-1:-1;;;;;43451:211:0;;:::i;19637:127::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;19637:127:0;;:::i;21538:230::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;21538:230:0;;;;;;-1:-1:-1;;;;;21538:230:0;;:::i;44376:1652::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;;;;;44376:1652:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11:28;;8:2;;;52:1;49;42:12;8:2;44376:1652:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;44376:1652:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;44376:1652:0;;-1:-1:-1;44376:1652:0;-1:-1:-1;44376:1652:0;:::i;42119:105::-;;;:::i;43733:246::-;-1:-1:-1;;;43733:246:0;;;;;;;:::o;20690:114::-;20747:7;20774:12;;;;;;;;;;:22;;;20690:114;;;;:::o;21066:227::-;21158:6;:12;;;;;;;;;;:22;;;21150:45;;21182:12;:10;:12::i;:::-;21150:7;:45::i;:::-;21142:105;;;;-1:-1:-1;;;21142:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21260:25;21271:4;21277:7;21260:10;:25::i;:::-;21066:227;;:::o;22275:209::-;22373:12;:10;:12::i;:::-;-1:-1:-1;;;;;22362:23:0;:7;-1:-1:-1;;;;;22362:23:0;;22354:83;;;;-1:-1:-1;;;22354:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22450:26;22462:4;22468:7;22450:11;:26::i;42605:117::-;42656:66;42605:117;:::o;42802:125::-;42861:66;42802:125;:::o;42267:103::-;42304:66;42267:103;:::o;46419:4772::-;-1:-1:-1;;;;;;;;;;;24305:27:0;42158:66;24319:12;:10;:12::i;24305:27::-;24347:10;24283:85;;;;;-1:-1:-1;;;24283:85:0;;;;;;;;;;;;-1:-1:-1;;24283:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46597:37:::1;46637:24;:15;:3;:13;:15::i;:::-;:22;:24::i;:::-;46597:64;;46672:42;46717:22;:10;46728:1;46717:13;;;;;;;;;;;;;;:20;:22::i;:::-;46672:67;;42477:66;46882:18;;46850:27;:15;46866:1;46850:18;;;;;;;;;;;;;;:25;:27::i;:::-;46842:58;46839:4335;;;46919:18;46948:27;:15;46964:1;46948:18;;;;;;;:27;46919:57;;47093:1;-1:-1:-1::0;;;;;47045:50:0::1;47053:27;:15;47069:1;47053:18;;;;;;;:27;-1:-1:-1::0;;;;;47045:50:0::1;;47019:177;;;;-1:-1:-1::0;;;47019:177:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47213:21;47253:9;47213:50;;47280:15;47298:27;:15;47314:1;47298:18;;;;;;;:27;47280:45;;47371:5;-1:-1:-1::0;;;;;47371:12:0::1;;47384:7;47371:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;47371:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;47371:21:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;47371:21:0;47367:274:::1;;;47413:140;::::0;;-1:-1:-1;;;47413:140:0;;47466:4:::1;47413:140;::::0;::::1;::::0;-1:-1:-1;;;;;47413:140:0;;::::1;::::0;;;;;;;;;;;;:22;;::::1;::::0;::::1;::::0;:140;;;;;-1:-1:-1;;47413:140:0;;;;;;;;-1:-1:-1;47413:22:0;:140;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;47413:140:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;47413:140:0;;;;47367:274;;;47594:5;-1:-1:-1::0;;;;;47594:10:0::1;;47605;47617:7;47594:31;;;;;;;;;;;;;-1:-1:-1::0;;;;;47594:31:0::1;-1:-1:-1::0;;;;;47594:31:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;47594:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;47594:31:0;;;;47367:274;46839:4335;;;;;;42656:66;47704:24;;47672:27;:15;47688:1;47672:18;;;;;;;:27;47664:64;47660:3514;;;48133:18;48162:27;:15;48178:1;48162:18;;;;;;;:27;48133:57;;48274:20;48297:23;:10;48308:1;48297:13;;;;;;;;;;;;;;:21;:23::i;:::-;48274:46;;48338:25;48378:7;48367:32;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;48367:32:0;;;;;;;;;;;;;-1:-1:-1::0;;;14:3:::1;11:20;8:2;;;44:1;41::::0;34:12:::1;8:2;62:21:::0;;::::1;::::0;123:4:::1;114:14:::0;::::1;138:31:::0;;::::1;135:2;;;182:1;179::::0;172:12:::1;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1:::0;;;247:12:::1;244:29;233:116;230:2;;;362:1;359::::0;352:12:::1;230:2;373:25:::0;;-1:-1;48367:32:0;;421:4:-1::1;412:14:::0;;::::1;::::0;48367:32:0;::::1;::::0;::::1;::::0;412:14:-1;48367:32:0;23:1:-1::1;8:100;33:3;30:1;27:10;8:100;;;90:11:::0;;::::1;84:18:::0;71:11;;::::1;64:39:::0;52:2:::1;45:10;8:100;;;-1:-1:::0;;;;48367:32:0;;;::::1;;::::0;-1:-1:-1;;48431:15:0;;48337:62;;-1:-1:-1;48503:9:0;;-1:-1:-1;48414:14:0::1;::::0;-1:-1:-1;48530:702:0::1;48550:6;48546:1;:10;48530:702;;;48584:15;48602:8;48611:1;48602:11;;;;;;;;;;;;;;48584:29;;48765:5;-1:-1:-1::0;;;;;48765:12:0::1;;48778:7;48765:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;48765:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;48765:21:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;48765:21:0;48761:454:::1;;;48811:156;::::0;;-1:-1:-1;;;48811:156:0;;48868:4:::1;48811:156;::::0;::::1;::::0;-1:-1:-1;;;;;48811:156:0;;::::1;::::0;;;;;;;;;;;;:22;;::::1;::::0;::::1;::::0;:156;;;;;-1:-1:-1;;48811:156:0;;;;;;;;-1:-1:-1;48811:22:0;:156;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;48811:156:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;48811:156:0;;;;48761:454;;;49164:5;-1:-1:-1::0;;;;;49164:10:0::1;;49175;49187:7;49164:31;;;;;;;;;;;;;-1:-1:-1::0;;;;;49164:31:0::1;-1:-1:-1::0;;;;;49164:31:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;49164:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;49164:31:0;;;;48761:454;-1:-1:-1::0;48558:3:0::1;;48530:702;;;;47660:3514;;;;;;;;42861:66;49295:32;;49263:27;:15;49279:1;49263:18;;;;;;;:27;49255:72;49251:1923;;;50054:18;50083:27;:15;50099:1;50083:18;;;;;;;:27;50054:57;;50228:1;-1:-1:-1::0;;;;;50180:50:0::1;50188:27;:15;50204:1;50188:18;;;;;;;:27;-1:-1:-1::0;;;;;50180:50:0::1;;50154:177;;;;-1:-1:-1::0;;;50154:177:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50348:21;50388:9;50348:50;;50415:15;50433:27;:15;50449:1;50433:18;;;;;;;:27;50415:45;;50506:5;-1:-1:-1::0;;;;;50506:12:0::1;;50519:7;50506:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;50506:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;50506:21:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;50506:21:0;50502:438:::1;;;50548:140;::::0;;-1:-1:-1;;;50548:140:0;;50601:4:::1;50548:140;::::0;::::1;::::0;-1:-1:-1;;;;;50548:140:0;;::::1;::::0;;;;;;;;;;;;:22;;::::1;::::0;::::1;::::0;:140;;;;;-1:-1:-1;;50548:140:0;;;;;;;;-1:-1:-1;50548:22:0;:140;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;50502:438:0;50868:5;-1:-1:-1::0;;;;;50868:10:0::1;;50879;50891:7;50900:23;:10;50911:1;50900:13;;;;;;;:23;50868:56;;;;;;;;;;;;;-1:-1:-1::0;;;;;50868:56:0::1;-1:-1:-1::0;;;;;50868:56:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11:::0;;::::1;84:18:::0;71:11;;::::1;64:39:::0;52:2:::1;45:10;8:100;;;12:14;50868:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;49251:1923:0;51110:52;;-1:-1:-1::0;;;51110:52:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49251:1923;24379:1;;46419:4772:::0;;;;:::o;20363:138::-;20436:7;20463:12;;;;;;;;;;:30;;20487:5;20463:30;:23;:30;:::i;:::-;20456:37;;20363:138;;;;;:::o;19324:139::-;19393:4;19417:12;;;;;;;;;;:38;;19447:7;19417:38;:29;:38;:::i;42999:40::-;43037:2;42999:40;:::o;18069:49::-;18114:4;18069:49;:::o;42432:111::-;42477:66;42432:111;:::o;43451:211::-;41711:6;;;;41710:7;41702:34;;;;;-1:-1:-1;;;41702:34:0;;;;;;;;;;;;-1:-1:-1;;;41702:34:0;;;;;;;;;;;;;;;43519:43:::1;;;;;;;;;;;;;;;;;::::0;:16:::1;:43::i;:::-;43573:38;18114:4;43604:6:::0;43573:10:::1;:38::i;:::-;43622:32;-1:-1:-1::0;;;;;;;;;;;43647:6:0;43622:10:::1;:32::i;:::-;-1:-1:-1::0;41759:6:0;:13;;-1:-1:-1;;41759:13:0;41768:4;41759:13;;;43451:211::o;19637:127::-;19700:7;19727:12;;;;;;;;;;:29;;:27;:29::i;21538:230::-;21631:6;:12;;;;;;;;;;:22;;;21623:45;;21655:12;:10;:12::i;21623:45::-;21615:106;;;;-1:-1:-1;;;21615:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44376:1652;-1:-1:-1;;;;;;;;;;;24305:27:0;42158:66;24319:12;:10;:12::i;24305:27::-;24347:10;24283:85;;;;;-1:-1:-1;;;24283:85:0;;;;;;;;;;;;-1:-1:-1;;24283:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44678:2:0::1;44656:24:::0;::::1;44652:1367;;;44699:15;44728:11;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;44853:68:0::1;::::0;;44717:34;::::1;44853:68:::0;;;;;44717:34;;-1:-1:-1;;;;;;44853:68:0;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;44717:34:::1;44853:68:::0;;::::1;45059:78;::::0;;-1:-1:-1;;;45059:78:0;;-1:-1:-1;;;;;45059:78:0;;::::1;;::::0;::::1;::::0;45122:4:::1;45059:78:::0;;;;;;;;;;;;:43;;::::1;::::0;::::1;::::0;:78;;;;;-1:-1:-1;;45059:78:0;;;;;;;;-1:-1:-1;45059:43:0;:78;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;45059:78:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;45059:78:0;;;;44652:1367;;;;45222:25;45261:11;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;45250:36:0::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;-1:-1:-1::0;;;11:28;::::1;8:2;;;52:1;49::::0;42:12:::1;8:2;45250:36:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61::::0;54:12:::1;8:2;45250:36:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1:::0;;;25:12:::1;22:29;11:108;8:2;;;132:1;129::::0;122:12:::1;8:2;45250:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;45250:36:0;;;;;;;;;;;;;;45222:64;;45483:9;-1:-1:-1::0;;;;;45429:74:0::1;45466:15;-1:-1:-1::0;;;;;45429:74:0::1;45455:9;-1:-1:-1::0;;;;;45429:74:0::1;;45494:8;45429:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11:::0;;::::1;84:18:::0;71:11;;::::1;64:39:::0;52:2:::1;45:10;8:100;;;12:14;45429:74:0;;;;;;;;;;;;;;;;;45625:15:::0;;43037:2:::1;45663:21:::0;::::1;;45655:78;;;;-1:-1:-1::0;;;45655:78:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45857:9;45852:154;45872:6;45868:1;:10;45852:154;;;45922:9;-1:-1:-1::0;;;;;45906:43:0::1;;45950:9;45969:4;45976:8;45985:1;45976:11;;;;;;;;;;;;;;45906:82;;;;;;;;;;;;;-1:-1:-1::0;;;;;45906:82:0::1;-1:-1:-1::0;;;;;45906:82:0::1;;;;;;-1:-1:-1::0;;;;;45906:82:0::1;-1:-1:-1::0;;;;;45906:82:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;45906:82:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;-1:-1:::0;;45880:3:0::1;::::0;;::::1;::::0;-1:-1:-1;45852:154:0::1;::::0;-1:-1:-1;45852:154:0::1;;;44652:1367;;44376:1652:::0;;;;;;:::o;42119:105::-;-1:-1:-1;;;;;;;;;;;42119:105:0;:::o;15979:106::-;16067:10;15979:106;;:::o;23518:188::-;23592:6;:12;;;;;;;;;;:33;;23617:7;23592:33;:24;:33;:::i;:::-;23588:111;;;23674:12;:10;:12::i;:::-;-1:-1:-1;;;;;23647:40:0;23665:7;-1:-1:-1;;;;;23647:40:0;23659:4;23647:40;;;;;;;;;;23518:188;;:::o;23714:192::-;23789:6;:12;;;;;;;;;;:36;;23817:7;23789:36;:27;:36;:::i;:::-;23785:114;;;23874:12;:10;:12::i;:::-;-1:-1:-1;;;;;23847:40:0;23865:7;-1:-1:-1;;;;;23847:40:0;23859:4;23847:40;;;;;;;;;;23714:192;;:::o;25065:330::-;25153:14;;:::i;:::-;25207:1;25193:4;:11;:15;25185:59;;;;;-1:-1:-1;;;25185:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25359:28:0;;;;;;;;;25367:11;;25359:28;;25324:4;25314:15;;;25359:28;;;;25065:330;;;:::o;25466:735::-;25553:16;25595:12;25602:4;25595:6;:12::i;:::-;25587:49;;;;;-1:-1:-1;;;25587:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;25649:13;25665:14;25674:4;25665:8;:14::i;:::-;25649:30;;25690:23;25730:5;25716:20;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;25716:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;25690:46;;25747:18;25768:24;25780:4;:11;;;25768;:24::i;:::-;25825:8;;25747:45;;-1:-1:-1;25811:22:0;;25803:74;;;;-1:-1:-1;;;25803:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25890:14;25921:27;25936:4;:11;;;25921:14;:27::i;:::-;25907:11;;;;:41;;-1:-1:-1;25959:15:0;;25985:183;26009:5;26005:1;:9;25985:183;;;26046:19;26058:6;26046:11;:19::i;:::-;26036:29;;26092:24;;;;;;;;26100:7;26092:24;;;;26109:6;26092:24;;;26080:6;26087:1;26080:9;;;;;;;;;;;;;;;;;:36;26140:16;;;;26016:3;;25985:183;;;-1:-1:-1;26187:6:0;;25466:735;-1:-1:-1;;;;;;25466:735:0:o;27351:792::-;27411:7;27440:12;27447:4;27440:6;:12::i;:::-;27439:13;27431:58;;;;;-1:-1:-1;;;27431:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27508:8;;27520:2;-1:-1:-1;27508:14:0;27500:57;;;;;-1:-1:-1;;;27500:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;27570:18;27591:24;27603:4;:11;;;27591;:24::i;:::-;27648:8;;27570:45;;-1:-1:-1;27634:22:0;;27626:74;;;;-1:-1:-1;;;27626:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27713:14;27730:27;27745:4;:11;;;27730:14;:27::i;:::-;27782:8;;27852:11;;;;;:20;;27917:13;;27713:44;;-1:-1:-1;27782:17:0;;;;;27917:13;27852:20;28008:11;;28005:2;;;28078:3;28074:2;28070:12;28065:3;28061:22;28053:6;28049:35;28039:45;;28005:2;-1:-1:-1;28129:6:0;27351:792;-1:-1:-1;;;;;27351:792:0:o;28689:564::-;28750:12;28775:18;28796:24;28808:4;:11;;;28796;:24::i;:::-;28853:8;;28775:45;;-1:-1:-1;28839:22:0;;28831:75;;;;-1:-1:-1;;;28831:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28917:14;28934:27;28949:4;:11;;;28934:14;:27::i;:::-;28988:8;;28917:44;;-1:-1:-1;28988:17:0;;;29031:19;28988:17;29053:14;;;2:2:-1;;;;27:1;24;17:12;2:2;29053:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;29053::0;87:42:-1;143:17;;-1:-1;29053:14:0;;29031:36;;29080:15;29151:6;29145:4;29141:17;29130:28;;29181:40;29200:6;29186:4;:11;;;:20;29208:7;29217:3;29181:4;:40::i;7284:149::-;7358:7;7401:22;7405:3;7417:5;7401:3;:22::i;6579:158::-;6659:4;6683:46;6693:3;-1:-1:-1;;;;;6713:14:0;;6683:9;:46::i;24077:159::-;24186:10;24169:58;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;365:33;;24169:58:0;;;;;;;;;;;26:21:-1;;;-1:-1;;22:32;6:49;;24169:58:0;;;;;;24149:79;;;;-1:-1:-1;274:1;;-1:-1;24149:79:0;;;;-1:-1:-1;24149:79:0;:::i;6823:117::-;6886:7;6913:19;6921:3;6913:7;:19::i;6025:143::-;6095:4;6119:41;6124:3;-1:-1:-1;;;;;6144:14:0;;6119:4;:41::i;6344:149::-;6417:4;6441:44;6449:3;-1:-1:-1;;;;;6469:14:0;;6441:7;:44::i;26308:288::-;26424:11;;;;26487:13;;26368:4;;26479:22;;;;24839:4;26528:24;;26524:42;;;26561:5;26554:12;;;;;;26524:42;-1:-1:-1;26584:4:0;;26308:288;-1:-1:-1;;;26308:288:0:o;29368:660::-;29429:7;29624:13;29640:1;29624:17;;29652:15;29684:27;29699:4;:11;;;29684:14;:27::i;:::-;29670:11;;;;29753:8;;29670:41;;;;-1:-1:-1;29739:22:0;29772:224;29789:6;29779:7;:16;29772:224;;;29832:20;29844:7;29832:11;:20::i;:::-;29822:7;:30;29812:40;;29907:6;29896:7;:17;;29888:74;;;;-1:-1:-1;;;29888:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29977:7;;;;;29772:224;;;-1:-1:-1;30015:5:0;;29368:660;-1:-1:-1;;;29368:660:0:o;30080:1275::-;30250:13;;30139:7;;;;30242:22;;24748:4;30291:26;;30287:1034;;;30329:1;30319:11;;30287:1034;;;24794:4;30350:25;;30346:975;;;-1:-1:-1;;30400:30:0;;;-1:-1:-1;30346:975:0;;;24839:4;30450:24;;30446:875;;;30545:4;30538:5;30534:16;30625:1;30617:6;30613:14;30603:24;;30767:7;30763:2;30759:16;30754:3;30750:26;30741:6;30735:13;30731:46;30865:1;30856:7;30852:15;30843:7;30839:29;30828:40;;;;30500:383;;;24883:4;30904:23;;30900:421;;;-1:-1:-1;;30954:28:0;;;-1:-1:-1;30900:421:0;;;31069:4;31062:5;31058:16;31114:1;31106:6;31102:14;31092:24;;31187:7;31183:2;31179:16;31174:3;31170:26;31161:6;31155:13;31151:46;31292:1;31283:7;31279:15;31270:7;31266:29;31255:40;;;;31024:286;-1:-1:-1;31340:7:0;30080:1275;-1:-1:-1;;30080:1275:0:o;31410:570::-;31557:13;;31472:7;;31549:22;;24748:4;31598:26;;31594:378;;;31633:1;31626:8;;;;;31594:378;24794:4;31668:25;;;:96;;-1:-1:-1;24839:4:0;31711:25;;;;;:52;;-1:-1:-1;24883:4:0;31740:23;;31711:52;31650:322;;;31783:1;31776:8;;;;;31650:322;24839:4;31804:24;;31800:172;;;-1:-1:-1;;31881:35:0;;-1:-1:-1;31874:42:0;;31800:172;-1:-1:-1;;31939:33:0;;-1:-1:-1;31932:40:0;;32145:761;32261:8;32257:21;;32271:7;;32257:21;32338:201;24921:2;32345:16;;32338:201;;32437:10;;32424:24;;24921:2;32479:16;;;;32510:17;;;;-1:-1:-1;;32363:16:0;32338:201;;;32727:10;;32799:11;;24921:2;32653:15;;;32647:3;:22;-1:-1:-1;;32647:26:0;32739:9;;32723:26;;;32795:22;;32866:21;32853:35;;32693:206;;;;:::o;5567:204::-;5662:18;;5634:7;;5662:26;-1:-1:-1;5654:73:0;;;;-1:-1:-1;;;5654:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5745:3;:11;;5757:5;5745:18;;;;;;;;;;;;;;;;5738:25;;5567:204;;;;:::o;4899:129::-;4972:4;4996:19;;;:12;;;;;:19;;;;;;:24;;;4899:129::o;5114:109::-;5197:18;;5114:109::o;2679:414::-;2742:4;2764:21;2774:3;2779:5;2764:9;:21::i;:::-;2759:327;;-1:-1:-1;27:10;;39:1;23:18;;;45:23;;2802:11:0;:23;;;;;;;;;;;;;2985:18;;2963:19;;;:12;;;:19;;;;;;:40;;;;3018:11;;2759:327;-1:-1:-1;3069:5:0;3062:12;;3269:1544;3335:4;3474:19;;;:12;;;:19;;;;;;3510:15;;3506:1300;;3945:18;;-1:-1:-1;;3896:14:0;;;;3945:22;;;;3872:21;;3945:3;;:22;;4232;;;;;;;;;;;;;;4212:42;;4378:9;4349:3;:11;;4361:13;4349:26;;;;;;;;;;;;;;;;;;;:38;;;;4455:23;;;4497:1;4455:12;;;:23;;;;;;4481:17;;;4455:43;;4607:17;;4455:3;;4607:17;;;;;;;;;;;;;;;;;;;;;;4702:3;:12;;:19;4715:5;4702:19;;;;;;;;;;;4695:26;;;4745:4;4738:11;;;;;;;;3506:1300;4789:5;4782:12;;;;;41896:9298;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41896:9298:0;;;-1:-1:-1;41896:9298:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;
Swarm Source
ipfs://55f4047592f7fc9a84a90b99abfaf361fc1c15addcb132a1678d94309ce107cf
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.