Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- ValeriaLandBeforeTheWar
- Optimization enabled
- true
- Compiler version
- v0.8.24+commit.e11b9ed9
- Optimization runs
- 1000
- EVM Version
- paris
- Verified at
- 2024-07-18T06:59:44.801390Z
Constructor Arguments
0x000000000000000000000000a87dbcfa18adb7c00593e2c2469d83213c87aecd000000000000000000000000ae975071be8f8ee67addbc1a82488f1c24858067000000000000000000000000f0511f123164602042ab2bcf02111fa5d3fe97cdd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a8000000000000000000000000000000000000000000000000000000000000042b0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000754a3c4b373bcf24895997c59d866ff0b7ae6113000000000000000000000000000000000000000000000000000000000000028a000000000000000000000000000000000000000000000000000000000000004768747470733a2f2f616c6c6f667468657468696e67732e73332e616d617a6f6e6177732e636f6d2f76616c657269612f6c6274772f6d657461646174612f7b69647d2e6a736f6e00000000000000000000000000000000000000000000000000
Arg [0] (address) : 0xa87dbcfa18adb7c00593e2c2469d83213c87aecd
Arg [1] (address) : 0xae975071be8f8ee67addbc1a82488f1c24858067
Arg [2] (address) : 0xf0511f123164602042ab2bcf02111fa5d3fe97cd
Arg [3] (bytes32) : d729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a8
Arg [4] (uint64) : 1067
Arg [5] (string) : https://allofthethings.s3.amazonaws.com/valeria/lbtw/metadata/{id}.json
Arg [6] (address) : 0x754a3c4b373bcf24895997c59d866ff0b7ae6113
Arg [7] (uint96) : 650
contracts/ValeriaLandBeforeTheWar.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol"; import {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol"; import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import {ERC1155OpenZeppelin, ERC1155C} from "@limitbreak/creator-token-contracts/contracts/erc1155c/ERC1155C.sol"; import {ERC2981, BasicRoyalties} from "@limitbreak/creator-token-contracts/contracts/programmable-royalties/BasicRoyalties.sol"; import {IValeriaBoosterPacks} from "./interfaces/IValeriaBoosterPacks.sol"; import {DynamicERC2711Context, Context} from "./extensions/DynamicERC2711Context.sol"; /** __ __ _ _ \ \ / /_ _| | ___ _ __(_) __ _ \ \ / / _` | |/ _ \ '__| |/ _` | \ V / (_| | | __/ | | | (_| | \_/ \__,_|_|\___|_| |_|\__,_| */ /// @title ValeriaLandBeforeTheWar /// @notice The Valeria Land Before The War collection. /// Burn a Booster pack for a distribution of valerians/champions /// Allows the option for external contracts to burn/mint /// @author @ValeriaStudios contract ValeriaLandBeforeTheWar is AccessControl, ERC1155C, DynamicERC2711Context, BasicRoyalties, VRFConsumerBaseV2, IValeriaBoosterPacks { // VRF V2 VRFCoordinatorV2Interface immutable COORDINATOR; bytes32 public immutable keyHash; uint64 public immutable subscriptionId; uint16 constant numWords = 1; // Roles bytes32 public constant MODERATOR_ROLE = keccak256("MODERATOR_ROLE"); bytes32 public constant EXTERNAL_CONTRACT_ROLE = keccak256("EXTERNAL_CONTRACT_ROLE"); struct PackConfiguration { uint256 packId; uint256 quantity; uint256[] itemIds; uint256[] probabilities; uint256[] aliases; } struct PackOpenRequest { address requester; uint256 packId; uint256 amount; } event RandomnessRequest(uint256 indexed requestId, uint256 indexed packId); event PackOpened( uint256 indexed requestId, address indexed to, uint256 randomness, uint256 packId, uint256 amount, uint256[] tokenIds ); error IsPaused(); error MaxPacksPerTransaction(); error InvalidPackConfiguration(); IValeriaBoosterPacks boosterPacksContract; /// @dev Whether pack openings are live or not bool public isPaused = true; /// @dev Use VRF configuration for openings bool public useVRF = false; /// @notice Nonce counter for pseudo requests uint256 private requestNonce; /// @dev Max packs you can open per transaction uint256 public maxPacksPerTx = 20; /// @dev VRF callback limit uint32 public vrfGasLimit = 500000; /// @dev requestId => drop config at time of request mapping(uint256 => PackOpenRequest) private requestIdToRequestConfig; /// @dev packId => opening config at time of request mapping(uint256 => PackConfiguration) public configurations; constructor( address _boosterPacksContractAddress, address _vrfV2Coordinator, address _trustedForwarder, bytes32 keyHash_, uint64 subscriptionId_, string memory _uri, address royaltyReceiver_, uint96 royaltyFeeNumerator_ ) VRFConsumerBaseV2(_vrfV2Coordinator) ERC1155OpenZeppelin(_uri) BasicRoyalties(royaltyReceiver_, royaltyFeeNumerator_) DynamicERC2711Context(_trustedForwarder) { // Roles _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); _grantRole(MODERATOR_ROLE, _msgSender()); // Chainlink COORDINATOR = VRFCoordinatorV2Interface(_vrfV2Coordinator); keyHash = keyHash_; subscriptionId = subscriptionId_; // Associated contracts boosterPacksContract = IValeriaBoosterPacks( _boosterPacksContractAddress ); } function name() external pure returns (string memory) { return "Valeria: Land Before The War"; } function symbol() external pure returns (string memory) { return "VALBTW"; } /** * PACK OPENING */ /** * @notice Opens a set of packs for a particular token id * @dev Emits a pack opening outcome * @param packId - The token id of a particular pack * @param amount - The amount of packs to open */ function open(uint256 packId, uint256 amount) external { if (isPaused) revert IsPaused(); if (amount > maxPacksPerTx) revert MaxPacksPerTransaction(); PackConfiguration storage config = configurations[packId]; if (config.packId != packId) revert InvalidPackConfiguration(); address requester = _msgSender(); boosterPacksContract.burnItem(requester, packId, amount); uint256 requestId; // Process opening sequence thru vrf or pseudorandom if (useVRF) { requestId = COORDINATOR.requestRandomWords( _keyHash(), _subscriptionId(), 3, vrfGasLimit, numWords ); _processRandomnessRequest(requestId, packId, amount, requester); emit RandomnessRequest(requestId, packId); } else { requestNonce++; // Bump internal request nonce for request id usage _processFulfillment( requestNonce, configurations[packId], pseudorandom(requestNonce), amount, requester ); } } /// @dev AJ-walker alias algo selection O(1), probabilities and alias computed off-chain and saved as configuration function _chooseItem( uint256 seed, uint256[] memory probabilities, uint256[] memory aliases ) internal pure returns (uint256) { uint256 traitSeed = seed & 0xFFFF; uint256 trait = traitSeed % probabilities.length; if (traitSeed >> 8 < probabilities[trait]) return trait; return aliases[trait]; } function _processFulfillment( uint256 requestId, PackConfiguration memory config, uint256 randomness, uint256 amount, address requester ) internal { uint256 mintQuantity = config.quantity * amount; uint256[] memory ids = new uint256[](mintQuantity); uint256 seed; uint256 indexChosen; uint256 i = 0; for (; i < mintQuantity; i++) { seed = (randomness / ((i + 1) * 10)) % 2 ** 32; indexChosen = _chooseItem( seed, config.probabilities, config.aliases ); ids[i] = config.itemIds[indexChosen]; } _mintOpenedItems(requester, ids); emit PackOpened( requestId, requester, randomness, config.packId, mintQuantity, ids ); } /** * @notice Mints tokens to a particular address * @param to - the address to mint items too * @param tokenIds - the token ids to mint */ function _mintOpenedItems(address to, uint256[] memory tokenIds) internal { uint256 amount = tokenIds.length; uint256[] memory ids = new uint256[](amount); uint256[] memory amounts = new uint256[](amount); for (uint256 i = 0; i < amount; i++) { ids[i] = tokenIds[i]; amounts[i] = 1; } _mintBatch(to, ids, amounts, ""); } /// @dev Handle setting request configuration for a given request id function _handlePackOpeningRequest( uint256 requestId, uint256 packId, uint256 amount, address requester ) internal { // Stores intermediate request state for later consumption requestIdToRequestConfig[requestId] = PackOpenRequest({ requester: requester, packId: packId, amount: amount }); } /// @dev Handle minting items related to a pack opening request function _handlePackOpeningFulfillment( uint256 requestId, uint256 randomness ) internal { PackOpenRequest storage requestConfig = requestIdToRequestConfig[ requestId ]; _processFulfillment( requestId, configurations[requestConfig.packId], randomness, requestConfig.amount, requestConfig.requester ); } /** * Chainlink integration */ /// @dev Handle randomness request function _processRandomnessRequest( uint256 requestId, uint256 packId, uint256 amount, address requester ) internal { _handlePackOpeningRequest(requestId, packId, amount, requester); } /// @dev Handles randomness fulfillment function _processRandomnessFulfillment( uint256 requestId, uint256 randomness ) internal { _handlePackOpeningFulfillment(requestId, randomness); } /// @dev Callback function used by VRF Coordinator function fulfillRandomWords( uint256 requestId, uint256[] memory randomWords ) internal override { _processRandomnessFulfillment(requestId, randomWords[0]); } function _keyHash() internal view returns (bytes32) { return keyHash; } function _subscriptionId() internal view returns (uint64) { return subscriptionId; } /// @dev if not using VRF, "randomness" function pseudorandom(uint256 nonce) private view returns (uint256) { return uint256( keccak256( abi.encodePacked(block.timestamp, block.prevrandao, nonce) ) ); } /** * @notice Returns the config information of specific set of pack token ids * @param packIds token ids to check against * @return bytes[] */ function configurationOf( uint256[] memory packIds ) external view returns (bytes[] memory) { bytes[] memory configs = new bytes[](packIds.length); PackConfiguration storage config; uint256 tokenId; for (uint256 i; i < packIds.length; i++) { tokenId = packIds[i]; config = configurations[tokenId]; configs[i] = abi.encode( config.packId, config.quantity, config.itemIds ); } return configs; } /** * EXTERNAL CONTRACT INTEGRATION */ /// @dev Allows an external contract w/ role to burn an item function burnItem( address owner, uint256 typeId, uint256 amount ) external onlyRole(EXTERNAL_CONTRACT_ROLE) { _burn(owner, typeId, amount); } /// @dev Allows an external contract w/ role to burn in batch function burnItems( address owner, uint256[] calldata typeIds, uint256[] calldata amounts ) external onlyRole(EXTERNAL_CONTRACT_ROLE) { _burnBatch(owner, typeIds, amounts); } /// @dev Allows an external contract w/ role to mint an item function mintItem( address to, uint256 typeId, uint256 amount ) external onlyRole(EXTERNAL_CONTRACT_ROLE) { _mint(to, typeId, amount, ""); } /// @dev Allows an external contract w/ role to mint a batch of items to the same address function mintItems( address to, uint256[] calldata typeIds, uint256[] calldata amounts ) external onlyRole(EXTERNAL_CONTRACT_ROLE) { _mintBatch(to, typeIds, amounts, ""); } /// @dev Allows a bulk transfer function bulkSafeTransfer( uint256 typeId, uint256 amount, address[] calldata recipients ) external { for (uint256 i; i < recipients.length; i++) { safeTransferFrom(_msgSender(), recipients[i], typeId, amount, ""); } } /** * MODERATOR */ /// @dev Permissions check function _requireCallerIsContractOwner() internal view virtual override { _checkRole(MODERATOR_ROLE); } /// @dev Allows a moderator to change the base uri function setURI(string memory _uri) public onlyRole(MODERATOR_ROLE) { _setURI(_uri); } /// @dev Configure default royalty function setDefaultRoyalty( address receiver, uint96 feeNumerator ) public onlyRole(MODERATOR_ROLE) { _setDefaultRoyalty(receiver, feeNumerator); } /// @dev Configure ongoing royalties function setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) public onlyRole(MODERATOR_ROLE) { _setTokenRoyalty(tokenId, receiver, feeNumerator); } /// @dev Determines whether to use VRF or not function setUseVRF(bool _useVRF) external onlyRole(MODERATOR_ROLE) { useVRF = _useVRF; } /** * @notice Sets the booster packs contract * @param _boosterPacksContractAddress - The address of the packs contract */ function setBoosterPackContract( address _boosterPacksContractAddress ) external onlyRole(MODERATOR_ROLE) { boosterPacksContract = IValeriaBoosterPacks( _boosterPacksContractAddress ); } /** * @notice Sets the booster packs contract * @param _maxPacksPerTx - The max amount of packs to open */ function setMaxPacksPerTransaction( uint256 _maxPacksPerTx ) external onlyRole(MODERATOR_ROLE) { maxPacksPerTx = _maxPacksPerTx; } /** * @notice Sets the vrf gas callback limit * @param _vrfGasLimit - A gas limit */ function setVRFCallbackLimit( uint32 _vrfGasLimit ) external onlyRole(MODERATOR_ROLE) { vrfGasLimit = _vrfGasLimit; } /** * @notice Sets pack configuration * @param config - The config object representing the pack */ function setPackConfiguration( PackConfiguration calldata config ) public onlyRole(MODERATOR_ROLE) { require(config.quantity > 0, "Mint quantity should be greater than 0"); require(config.itemIds.length > 0, "Must have at least 1 item"); require( config.probabilities.length == config.aliases.length, "Invalid config" ); configurations[config.packId] = config; } /** * @notice Sets the pause state * @param _isPaused The pause state */ function setPaused(bool _isPaused) external onlyRole(MODERATOR_ROLE) { isPaused = _isPaused; } /// @dev Allows a moderator to mint a single item function moderatorMint( address to, uint256 id, uint256 amount, bytes memory data ) external onlyRole(MODERATOR_ROLE) { _mint(to, id, amount, data); } /// @dev Allows a moderator to batch mint items function moderatorMintBatch( address to, uint256[] calldata ids, uint256[] calldata amounts, bytes memory data ) external onlyRole(MODERATOR_ROLE) { _mintBatch(to, ids, amounts, data); } /// @dev Allows a moderator to airdrop items to multiple addresses function moderatorAirdrop( address[] calldata tos, uint256[][] calldata ids, uint256[][] calldata amounts, bytes memory data ) external onlyRole(MODERATOR_ROLE) { require( tos.length == ids.length && ids.length == amounts.length, "!valid" ); for (uint256 i; i < tos.length; i++) { _mintBatch(tos[i], ids[i], amounts[i], data); } } // ======================================== // Native meta transactions // ======================================== function _msgSender() internal view virtual override(Context, DynamicERC2711Context) returns (address) { return DynamicERC2711Context._msgSender(); } function _msgData() internal view virtual override(Context, DynamicERC2711Context) returns (bytes calldata) { return DynamicERC2711Context._msgData(); } function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC1155C, ERC2981, AccessControl) returns (bool) { return super.supportsInterface(interfaceId); } }
@openzeppelin/contracts/utils/Strings.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
@openzeppelin/contracts/token/common/ERC2981.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/common/ERC2981.sol) pragma solidity ^0.8.0; import "../../interfaces/IERC2981.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information. * * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first. * * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the * fee is specified in basis points by default. * * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported. * * _Available since v4.5._ */ abstract contract ERC2981 is IERC2981, ERC165 { struct RoyaltyInfo { address receiver; uint96 royaltyFraction; } RoyaltyInfo private _defaultRoyaltyInfo; mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } /** * @inheritdoc IERC2981 */ function royaltyInfo(uint256 _tokenId, uint256 _salePrice) public view virtual override returns (address, uint256) { RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId]; if (royalty.receiver == address(0)) { royalty = _defaultRoyaltyInfo; } uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) / _feeDenominator(); return (royalty.receiver, royaltyAmount); } /** * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an * override. */ function _feeDenominator() internal pure virtual returns (uint96) { return 10000; } /** * @dev Sets the royalty information that all ids in this contract will default to. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: invalid receiver"); _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Removes default royalty information. */ function _deleteDefaultRoyalty() internal virtual { delete _defaultRoyaltyInfo; } /** * @dev Sets the royalty information for a specific token id, overriding the global default. * * Requirements: * * - `receiver` cannot be the zero address. * - `feeNumerator` cannot be greater than the fee denominator. */ function _setTokenRoyalty( uint256 tokenId, address receiver, uint96 feeNumerator ) internal virtual { require(feeNumerator <= _feeDenominator(), "ERC2981: royalty fee will exceed salePrice"); require(receiver != address(0), "ERC2981: Invalid parameters"); _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator); } /** * @dev Resets royalty information for the token id back to the global default. */ function _resetTokenRoyalty(uint256 tokenId) internal virtual { delete _tokenRoyaltyInfo[tokenId]; } }
@openzeppelin/contracts/access/AccessControl.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
@limitbreak/creator-token-contracts/contracts/interfaces/ITransferSecurityRegistry.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../utils/TransferPolicy.sol"; interface ITransferSecurityRegistry { event AddedToAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account); event CreatedAllowlist(AllowlistTypes indexed kind, uint256 indexed id, string indexed name); event ReassignedAllowlistOwnership(AllowlistTypes indexed kind, uint256 indexed id, address indexed newOwner); event RemovedFromAllowlist(AllowlistTypes indexed kind, uint256 indexed id, address indexed account); event SetAllowlist(AllowlistTypes indexed kind, address indexed collection, uint120 indexed id); event SetTransferSecurityLevel(address indexed collection, TransferSecurityLevels level); function createOperatorWhitelist(string calldata name) external returns (uint120); function createPermittedContractReceiverAllowlist(string calldata name) external returns (uint120); function reassignOwnershipOfOperatorWhitelist(uint120 id, address newOwner) external; function reassignOwnershipOfPermittedContractReceiverAllowlist(uint120 id, address newOwner) external; function renounceOwnershipOfOperatorWhitelist(uint120 id) external; function renounceOwnershipOfPermittedContractReceiverAllowlist(uint120 id) external; function setTransferSecurityLevelOfCollection(address collection, TransferSecurityLevels level) external; function setOperatorWhitelistOfCollection(address collection, uint120 id) external; function setPermittedContractReceiverAllowlistOfCollection(address collection, uint120 id) external; function addOperatorToWhitelist(uint120 id, address operator) external; function addPermittedContractReceiverToAllowlist(uint120 id, address receiver) external; function removeOperatorFromWhitelist(uint120 id, address operator) external; function removePermittedContractReceiverFromAllowlist(uint120 id, address receiver) external; function getCollectionSecurityPolicy(address collection) external view returns (CollectionSecurityPolicy memory); function getWhitelistedOperators(uint120 id) external view returns (address[] memory); function getPermittedContractReceivers(uint120 id) external view returns (address[] memory); function isOperatorWhitelisted(uint120 id, address operator) external view returns (bool); function isContractReceiverPermitted(uint120 id, address receiver) external view returns (bool); }
@openzeppelin/contracts/token/ERC1155/ERC1155.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol) pragma solidity ^0.8.0; import "./IERC1155.sol"; import "./IERC1155Receiver.sol"; import "./extensions/IERC1155MetadataURI.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of the basic standard multi-token. * See https://eips.ethereum.org/EIPS/eip-1155 * Originally based on code by Enjin: https://github.com/enjin/erc-1155 * * _Available since v3.1._ */ contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI { using Address for address; // Mapping from token ID to account balances mapping(uint256 => mapping(address => uint256)) private _balances; // Mapping from account to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json string private _uri; /** * @dev See {_setURI}. */ constructor(string memory uri_) { _setURI(uri_); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC1155).interfaceId || interfaceId == type(IERC1155MetadataURI).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC1155MetadataURI-uri}. * * This implementation returns the same URI for *all* token types. It relies * on the token type ID substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * Clients calling this function must replace the `\{id\}` substring with the * actual token type ID. */ function uri(uint256) public view virtual override returns (string memory) { return _uri; } /** * @dev See {IERC1155-balanceOf}. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { require(account != address(0), "ERC1155: address zero is not a valid owner"); return _balances[id][account]; } /** * @dev See {IERC1155-balanceOfBatch}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual override returns (uint256[] memory) { require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch"); uint256[] memory batchBalances = new uint256[](accounts.length); for (uint256 i = 0; i < accounts.length; ++i) { batchBalances[i] = balanceOf(accounts[i], ids[i]); } return batchBalances; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { return _operatorApprovals[account][operator]; } /** * @dev See {IERC1155-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual override { require( from == _msgSender() || isApprovedForAll(from, _msgSender()), "ERC1155: caller is not token owner or approved" ); _safeTransferFrom(from, to, id, amount, data); } /** * @dev See {IERC1155-safeBatchTransferFrom}. */ function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual override { require( from == _msgSender() || isApprovedForAll(from, _msgSender()), "ERC1155: caller is not token owner or approved" ); _safeBatchTransferFrom(from, to, ids, amounts, data); } /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: transfer to the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, to, ids, amounts, data); uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; emit TransferSingle(operator, from, to, id, amount); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); require(to != address(0), "ERC1155: transfer to the zero address"); address operator = _msgSender(); _beforeTokenTransfer(operator, from, to, ids, amounts, data); for (uint256 i = 0; i < ids.length; ++i) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: insufficient balance for transfer"); unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; } emit TransferBatch(operator, from, to, ids, amounts); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); } /** * @dev Sets a new URI for all token types, by relying on the token type ID * substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * By this mechanism, any occurrence of the `\{id\}` substring in either the * URI or any of the amounts in the JSON file at said URI will be replaced by * clients with the token type ID. * * For example, the `https://token-cdn-domain/\{id\}.json` URI would be * interpreted by clients as * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` * for token type ID 0x4cce0. * * See {uri}. * * Because these URIs cannot be meaningfully represented by the {URI} event, * this function emits no events. */ function _setURI(string memory newuri) internal virtual { _uri = newuri; } /** * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); _balances[id][to] += amount; emit TransferSingle(operator, address(0), to, id, amount); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _mintBatch( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require(to != address(0), "ERC1155: mint to the zero address"); require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); address operator = _msgSender(); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); for (uint256 i = 0; i < ids.length; i++) { _balances[ids[i]][to] += amounts[i]; } emit TransferBatch(operator, address(0), to, ids, amounts); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); } /** * @dev Destroys `amount` tokens of token type `id` from `from` * * Emits a {TransferSingle} event. * * Requirements: * * - `from` cannot be the zero address. * - `from` must have at least `amount` tokens of token type `id`. */ function _burn( address from, uint256 id, uint256 amount ) internal virtual { require(from != address(0), "ERC1155: burn from the zero address"); address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); unchecked { _balances[id][from] = fromBalance - amount; } emit TransferSingle(operator, from, address(0), id, amount); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. */ function _burnBatch( address from, uint256[] memory ids, uint256[] memory amounts ) internal virtual { require(from != address(0), "ERC1155: burn from the zero address"); require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch"); address operator = _msgSender(); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); for (uint256 i = 0; i < ids.length; i++) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; require(fromBalance >= amount, "ERC1155: burn amount exceeds balance"); unchecked { _balances[id][from] = fromBalance - amount; } } emit TransferBatch(operator, from, address(0), ids, amounts); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC1155: setting approval status for self"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Hook that is called before any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `ids` and `amounts` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `id` and `amount` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} function _doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) private { if (to.isContract()) { try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) { if (response != IERC1155Receiver.onERC1155Received.selector) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non-ERC1155Receiver implementer"); } } } function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.isContract()) { try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response ) { if (response != IERC1155Receiver.onERC1155BatchReceived.selector) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non-ERC1155Receiver implementer"); } } } function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { uint256[] memory array = new uint256[](1); array[0] = element; return array; } }
@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** **************************************************************************** * @notice Interface for contracts using VRF randomness * ***************************************************************************** * @dev PURPOSE * * @dev Reggie the Random Oracle (not his real job) wants to provide randomness * @dev to Vera the verifier in such a way that Vera can be sure he's not * @dev making his output up to suit himself. Reggie provides Vera a public key * @dev to which he knows the secret key. Each time Vera provides a seed to * @dev Reggie, he gives back a value which is computed completely * @dev deterministically from the seed and the secret key. * * @dev Reggie provides a proof by which Vera can verify that the output was * @dev correctly computed once Reggie tells it to her, but without that proof, * @dev the output is indistinguishable to her from a uniform random sample * @dev from the output space. * * @dev The purpose of this contract is to make it easy for unrelated contracts * @dev to talk to Vera the verifier about the work Reggie is doing, to provide * @dev simple access to a verifiable source of randomness. It ensures 2 things: * @dev 1. The fulfillment came from the VRFCoordinator * @dev 2. The consumer contract implements fulfillRandomWords. * ***************************************************************************** * @dev USAGE * * @dev Calling contracts must inherit from VRFConsumerBase, and can * @dev initialize VRFConsumerBase's attributes in their constructor as * @dev shown: * * @dev contract VRFConsumer { * @dev constructor(<other arguments>, address _vrfCoordinator, address _link) * @dev VRFConsumerBase(_vrfCoordinator) public { * @dev <initialization with other arguments goes here> * @dev } * @dev } * * @dev The oracle will have given you an ID for the VRF keypair they have * @dev committed to (let's call it keyHash). Create subscription, fund it * @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface * @dev subscription management functions). * @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations, * @dev callbackGasLimit, numWords), * @dev see (VRFCoordinatorInterface for a description of the arguments). * * @dev Once the VRFCoordinator has received and validated the oracle's response * @dev to your request, it will call your contract's fulfillRandomWords method. * * @dev The randomness argument to fulfillRandomWords is a set of random words * @dev generated from your requestId and the blockHash of the request. * * @dev If your contract could have concurrent requests open, you can use the * @dev requestId returned from requestRandomWords to track which response is associated * @dev with which randomness request. * @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind, * @dev if your contract could have multiple requests in flight simultaneously. * * @dev Colliding `requestId`s are cryptographically impossible as long as seeds * @dev differ. * * ***************************************************************************** * @dev SECURITY CONSIDERATIONS * * @dev A method with the ability to call your fulfillRandomness method directly * @dev could spoof a VRF response with any random value, so it's critical that * @dev it cannot be directly called by anything other than this base contract * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method). * * @dev For your users to trust that your contract's random behavior is free * @dev from malicious interference, it's best if you can write it so that all * @dev behaviors implied by a VRF response are executed *during* your * @dev fulfillRandomness method. If your contract must store the response (or * @dev anything derived from it) and use it later, you must ensure that any * @dev user-significant behavior which depends on that stored value cannot be * @dev manipulated by a subsequent VRF request. * * @dev Similarly, both miners and the VRF oracle itself have some influence * @dev over the order in which VRF responses appear on the blockchain, so if * @dev your contract could have multiple VRF requests in flight simultaneously, * @dev you must ensure that the order in which the VRF responses arrive cannot * @dev be used to manipulate your contract's user-significant behavior. * * @dev Since the block hash of the block which contains the requestRandomness * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful * @dev miner could, in principle, fork the blockchain to evict the block * @dev containing the request, forcing the request to be included in a * @dev different block with a different hash, and therefore a different input * @dev to the VRF. However, such an attack would incur a substantial economic * @dev cost. This cost scales with the number of blocks the VRF oracle waits * @dev until it calls responds to a request. It is for this reason that * @dev that you can signal to an oracle you'd like them to wait longer before * @dev responding to the request (however this is not enforced in the contract * @dev and so remains effective only in the case of unmodified oracle software). */ abstract contract VRFConsumerBaseV2 { error OnlyCoordinatorCanFulfill(address have, address want); address private immutable vrfCoordinator; /** * @param _vrfCoordinator address of VRFCoordinator contract */ constructor(address _vrfCoordinator) { vrfCoordinator = _vrfCoordinator; } /** * @notice fulfillRandomness handles the VRF response. Your contract must * @notice implement it. See "SECURITY CONSIDERATIONS" above for important * @notice principles to keep in mind when implementing your fulfillRandomness * @notice method. * * @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this * @dev signature, and will call it once it has verified the proof * @dev associated with the randomness. (It is triggered via a call to * @dev rawFulfillRandomness, below.) * * @param requestId The Id initially returned by requestRandomness * @param randomWords the VRF output expanded to the requested number of words */ function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external { if (msg.sender != vrfCoordinator) { revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator); } fulfillRandomWords(requestId, randomWords); } }
@limitbreak/creator-token-contracts/contracts/token/erc1155/ERC1155OpenZeppelin.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../../access/OwnablePermissions.sol"; import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; abstract contract ERC1155OpenZeppelinBase is ERC1155 { } abstract contract ERC1155OpenZeppelin is ERC1155OpenZeppelinBase { constructor(string memory uri_) ERC1155(uri_) {} } abstract contract ERC1155OpenZeppelinInitializable is OwnablePermissions, ERC1155OpenZeppelinBase { error ERC1155OpenZeppelinInitializable__AlreadyInitializedERC1155(); bool private _erc1155Initialized; function initializeERC1155(string memory uri_) public { _requireCallerIsContractOwner(); if(_erc1155Initialized) { revert ERC1155OpenZeppelinInitializable__AlreadyInitializedERC1155(); } _erc1155Initialized = true; _setURI(uri_); } }
@limitbreak/creator-token-contracts/contracts/interfaces/ICreatorTokenTransferValidator.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "./IEOARegistry.sol"; import "./ITransferSecurityRegistry.sol"; import "./ITransferValidator.sol"; interface ICreatorTokenTransferValidator is ITransferSecurityRegistry, ITransferValidator, IEOARegistry {}
@limitbreak/creator-token-contracts/contracts/access/OwnablePermissions.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/utils/Context.sol"; abstract contract OwnablePermissions is Context { function _requireCallerIsContractOwner() internal view virtual; }
@openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface 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); }
@openzeppelin/contracts/interfaces/IERC2981.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); }
@limitbreak/creator-token-contracts/contracts/interfaces/ITransferValidator.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../utils/TransferPolicy.sol"; interface ITransferValidator { function applyCollectionTransferPolicy(address caller, address from, address to) external view; }
@limitbreak/creator-token-contracts/contracts/utils/CreatorTokenBase.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../access/OwnablePermissions.sol"; import "../interfaces/ICreatorToken.sol"; import "../interfaces/ICreatorTokenTransferValidator.sol"; import "../utils/TransferValidation.sol"; import "@openzeppelin/contracts/interfaces/IERC165.sol"; /** * @title CreatorTokenBase * @author Limit Break, Inc. * @notice CreatorTokenBase is an abstract contract that provides basic functionality for managing token * transfer policies through an implementation of ICreatorTokenTransferValidator. This contract is intended to be used * as a base for creator-specific token contracts, enabling customizable transfer restrictions and security policies. * * <h4>Features:</h4> * <ul>Ownable: This contract can have an owner who can set and update the transfer validator.</ul> * <ul>TransferValidation: Implements the basic token transfer validation interface.</ul> * <ul>ICreatorToken: Implements the interface for creator tokens, providing view functions for token security policies.</ul> * * <h4>Benefits:</h4> * <ul>Provides a flexible and modular way to implement custom token transfer restrictions and security policies.</ul> * <ul>Allows creators to enforce policies such as whitelisted operators and permitted contract receivers.</ul> * <ul>Can be easily integrated into other token contracts as a base contract.</ul> * * <h4>Intended Usage:</h4> * <ul>Use as a base contract for creator token implementations that require advanced transfer restrictions and * security policies.</ul> * <ul>Set and update the ICreatorTokenTransferValidator implementation contract to enforce desired policies for the * creator token.</ul> */ abstract contract CreatorTokenBase is OwnablePermissions, TransferValidation, ICreatorToken { error CreatorTokenBase__InvalidTransferValidatorContract(); error CreatorTokenBase__SetTransferValidatorFirst(); address public constant DEFAULT_TRANSFER_VALIDATOR = address(0x0000721C310194CcfC01E523fc93C9cCcFa2A0Ac); TransferSecurityLevels public constant DEFAULT_TRANSFER_SECURITY_LEVEL = TransferSecurityLevels.One; uint120 public constant DEFAULT_OPERATOR_WHITELIST_ID = uint120(1); ICreatorTokenTransferValidator private transferValidator; /** * @notice Allows the contract owner to set the transfer validator to the official validator contract * and set the security policy to the recommended default settings. * @dev May be overridden to change the default behavior of an individual collection. */ function setToDefaultSecurityPolicy() public virtual { _requireCallerIsContractOwner(); setTransferValidator(DEFAULT_TRANSFER_VALIDATOR); ICreatorTokenTransferValidator(DEFAULT_TRANSFER_VALIDATOR).setTransferSecurityLevelOfCollection(address(this), DEFAULT_TRANSFER_SECURITY_LEVEL); ICreatorTokenTransferValidator(DEFAULT_TRANSFER_VALIDATOR).setOperatorWhitelistOfCollection(address(this), DEFAULT_OPERATOR_WHITELIST_ID); } /** * @notice Allows the contract owner to set the transfer validator to a custom validator contract * and set the security policy to their own custom settings. */ function setToCustomValidatorAndSecurityPolicy( address validator, TransferSecurityLevels level, uint120 operatorWhitelistId, uint120 permittedContractReceiversAllowlistId) public { _requireCallerIsContractOwner(); setTransferValidator(validator); ICreatorTokenTransferValidator(validator). setTransferSecurityLevelOfCollection(address(this), level); ICreatorTokenTransferValidator(validator). setOperatorWhitelistOfCollection(address(this), operatorWhitelistId); ICreatorTokenTransferValidator(validator). setPermittedContractReceiverAllowlistOfCollection(address(this), permittedContractReceiversAllowlistId); } /** * @notice Allows the contract owner to set the security policy to their own custom settings. * @dev Reverts if the transfer validator has not been set. */ function setToCustomSecurityPolicy( TransferSecurityLevels level, uint120 operatorWhitelistId, uint120 permittedContractReceiversAllowlistId) public { _requireCallerIsContractOwner(); ICreatorTokenTransferValidator validator = getTransferValidator(); if (address(validator) == address(0)) { revert CreatorTokenBase__SetTransferValidatorFirst(); } validator.setTransferSecurityLevelOfCollection(address(this), level); validator.setOperatorWhitelistOfCollection(address(this), operatorWhitelistId); validator.setPermittedContractReceiverAllowlistOfCollection(address(this), permittedContractReceiversAllowlistId); } /** * @notice Sets the transfer validator for the token contract. * * @dev Throws when provided validator contract is not the zero address and doesn't support * the ICreatorTokenTransferValidator interface. * @dev Throws when the caller is not the contract owner. * * @dev <h4>Postconditions:</h4> * 1. The transferValidator address is updated. * 2. The `TransferValidatorUpdated` event is emitted. * * @param transferValidator_ The address of the transfer validator contract. */ function setTransferValidator(address transferValidator_) public { _requireCallerIsContractOwner(); bool isValidTransferValidator = false; if(transferValidator_.code.length > 0) { try IERC165(transferValidator_).supportsInterface(type(ICreatorTokenTransferValidator).interfaceId) returns (bool supportsInterface) { isValidTransferValidator = supportsInterface; } catch {} } if(transferValidator_ != address(0) && !isValidTransferValidator) { revert CreatorTokenBase__InvalidTransferValidatorContract(); } emit TransferValidatorUpdated(address(transferValidator), transferValidator_); transferValidator = ICreatorTokenTransferValidator(transferValidator_); } /** * @notice Returns the transfer validator contract address for this token contract. */ function getTransferValidator() public view override returns (ICreatorTokenTransferValidator) { return transferValidator; } /** * @notice Returns the security policy for this token contract, which includes: * Transfer security level, operator whitelist id, permitted contract receiver allowlist id. */ function getSecurityPolicy() public view override returns (CollectionSecurityPolicy memory) { if (address(transferValidator) != address(0)) { return transferValidator.getCollectionSecurityPolicy(address(this)); } return CollectionSecurityPolicy({ transferSecurityLevel: TransferSecurityLevels.Zero, operatorWhitelistId: 0, permittedContractReceiversId: 0 }); } /** * @notice Returns the list of all whitelisted operators for this token contract. * @dev This can be an expensive call and should only be used in view-only functions. */ function getWhitelistedOperators() public view override returns (address[] memory) { if (address(transferValidator) != address(0)) { return transferValidator.getWhitelistedOperators( transferValidator.getCollectionSecurityPolicy(address(this)).operatorWhitelistId); } return new address[](0); } /** * @notice Returns the list of permitted contract receivers for this token contract. * @dev This can be an expensive call and should only be used in view-only functions. */ function getPermittedContractReceivers() public view override returns (address[] memory) { if (address(transferValidator) != address(0)) { return transferValidator.getPermittedContractReceivers( transferValidator.getCollectionSecurityPolicy(address(this)).permittedContractReceiversId); } return new address[](0); } /** * @notice Checks if an operator is whitelisted for this token contract. * @param operator The address of the operator to check. */ function isOperatorWhitelisted(address operator) public view override returns (bool) { if (address(transferValidator) != address(0)) { return transferValidator.isOperatorWhitelisted( transferValidator.getCollectionSecurityPolicy(address(this)).operatorWhitelistId, operator); } return false; } /** * @notice Checks if a contract receiver is permitted for this token contract. * @param receiver The address of the receiver to check. */ function isContractReceiverPermitted(address receiver) public view override returns (bool) { if (address(transferValidator) != address(0)) { return transferValidator.isContractReceiverPermitted( transferValidator.getCollectionSecurityPolicy(address(this)).permittedContractReceiversId, receiver); } return false; } /** * @notice Determines if a transfer is allowed based on the token contract's security policy. Use this function * to simulate whether or not a transfer made by the specified `caller` from the `from` address to the `to` * address would be allowed by this token's security policy. * * @notice This function only checks the security policy restrictions and does not check whether token ownership * or approvals are in place. * * @param caller The address of the simulated caller. * @param from The address of the sender. * @param to The address of the receiver. * @return True if the transfer is allowed, false otherwise. */ function isTransferAllowed(address caller, address from, address to) public view override returns (bool) { if (address(transferValidator) != address(0)) { try transferValidator.applyCollectionTransferPolicy(caller, from, to) { return true; } catch { return false; } } return true; } /** * @dev Pre-validates a token transfer, reverting if the transfer is not allowed by this token's security policy. * Inheriting contracts are responsible for overriding the _beforeTokenTransfer function, or its equivalent * and calling _validateBeforeTransfer so that checks can be properly applied during token transfers. * * @dev Throws when the transfer doesn't comply with the collection's transfer policy, if the transferValidator is * set to a non-zero address. * * @param caller The address of the caller. * @param from The address of the sender. * @param to The address of the receiver. */ function _preValidateTransfer( address caller, address from, address to, uint256 /*tokenId*/, uint256 /*value*/) internal virtual override { if (address(transferValidator) != address(0)) { transferValidator.applyCollectionTransferPolicy(caller, from, to); } } }
@limitbreak/creator-token-contracts/contracts/programmable-royalties/BasicRoyalties.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/token/common/ERC2981.sol"; /** * @title BasicRoyaltiesBase * @author Limit Break, Inc. * @dev Base functionality of an NFT mix-in contract implementing the most basic form of programmable royalties. */ abstract contract BasicRoyaltiesBase is ERC2981 { event DefaultRoyaltySet(address indexed receiver, uint96 feeNumerator); event TokenRoyaltySet(uint256 indexed tokenId, address indexed receiver, uint96 feeNumerator); function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal virtual override { super._setDefaultRoyalty(receiver, feeNumerator); emit DefaultRoyaltySet(receiver, feeNumerator); } function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual override { super._setTokenRoyalty(tokenId, receiver, feeNumerator); emit TokenRoyaltySet(tokenId, receiver, feeNumerator); } } /** * @title BasicRoyalties * @author Limit Break, Inc. * @notice Constructable BasicRoyalties Contract implementation. */ abstract contract BasicRoyalties is BasicRoyaltiesBase { constructor(address receiver, uint96 feeNumerator) { _setDefaultRoyalty(receiver, feeNumerator); } } /** * @title BasicRoyaltiesInitializable * @author Limit Break, Inc. * @notice Initializable BasicRoyalties Contract implementation to allow for EIP-1167 clones. */ abstract contract BasicRoyaltiesInitializable is BasicRoyaltiesBase {}
@limitbreak/creator-token-contracts/contracts/erc1155c/ERC1155C.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../utils/CreatorTokenBase.sol"; import "../token/erc1155/ERC1155OpenZeppelin.sol"; /** * @title ERC1155C * @author Limit Break, Inc. * @notice Extends OpenZeppelin's ERC1155 implementation with Creator Token functionality, which * allows the contract owner to update the transfer validation logic by managing a security policy in * an external transfer validation security policy registry. See {CreatorTokenTransferValidator}. */ abstract contract ERC1155C is ERC1155OpenZeppelin, CreatorTokenBase { function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(ICreatorToken).interfaceId || super.supportsInterface(interfaceId); } /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic function _beforeTokenTransfer( address /*operator*/, address from, address to, uint256[] memory ids, uint256[] memory /*amounts*/, bytes memory /*data*/ ) internal virtual override { uint256 idsArrayLength = ids.length; for (uint256 i = 0; i < idsArrayLength;) { _validateBeforeTransfer(from, to, ids[i]); unchecked { ++i; } } } /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic function _afterTokenTransfer( address /*operator*/, address from, address to, uint256[] memory ids, uint256[] memory /*amounts*/, bytes memory /*data*/ ) internal virtual override { uint256 idsArrayLength = ids.length; for (uint256 i = 0; i < idsArrayLength;) { _validateAfterTransfer(from, to, ids[i]); unchecked { ++i; } } } } /** * @title ERC1155CInitializable * @author Limit Break, Inc. * @notice Initializable implementation of ERC1155C to allow for EIP-1167 proxy clones. */ abstract contract ERC1155CInitializable is ERC1155OpenZeppelinInitializable, CreatorTokenBase { function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(ICreatorToken).interfaceId || super.supportsInterface(interfaceId); } /// @dev Ties the open-zeppelin _beforeTokenTransfer hook to more granular transfer validation logic function _beforeTokenTransfer( address /*operator*/, address from, address to, uint256[] memory ids, uint256[] memory /*amounts*/, bytes memory /*data*/ ) internal virtual override { uint256 idsArrayLength = ids.length; for (uint256 i = 0; i < idsArrayLength;) { _validateBeforeTransfer(from, to, ids[i]); unchecked { ++i; } } } /// @dev Ties the open-zeppelin _afterTokenTransfer hook to more granular transfer validation logic function _afterTokenTransfer( address /*operator*/, address from, address to, uint256[] memory ids, uint256[] memory /*amounts*/, bytes memory /*data*/ ) internal virtual override { uint256 idsArrayLength = ids.length; for (uint256 i = 0; i < idsArrayLength;) { _validateAfterTransfer(from, to, ids[i]); unchecked { ++i; } } } }
@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
contracts/extensions/DynamicERC2711Context.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract DynamicERC2711Context is Context, Ownable { address private _trustedForwarder; constructor(address initialTrustedForwarder) { _trustedForwarder = initialTrustedForwarder; } function isTrustedForwarder(address forwarder) public view virtual returns (bool) { return forwarder == _trustedForwarder; } function setTrustedForwarder(address newTrustedForwarder) external onlyOwner { _trustedForwarder = newTrustedForwarder; } function _msgSender() internal view virtual override returns (address sender) { if (isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. /// @solidity memory-safe-assembly assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } } else { return super._msgSender(); } } function _msgData() internal view virtual override returns (bytes calldata) { if (isTrustedForwarder(msg.sender)) { return msg.data[:msg.data.length - 20]; } else { return super._msgData(); } } }
@openzeppelin/contracts/interfaces/IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol";
@limitbreak/creator-token-contracts/contracts/utils/TransferValidation.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/utils/Context.sol"; /** * @title TransferValidation * @author Limit Break, Inc. * @notice A mix-in that can be combined with ERC-721 contracts to provide more granular hooks. * Openzeppelin's ERC721 contract only provides hooks for before and after transfer. This allows * developers to validate or customize transfers within the context of a mint, a burn, or a transfer. */ abstract contract TransferValidation is Context { error ShouldNotMintToBurnAddress(); /// @dev Inheriting contracts should call this function in the _beforeTokenTransfer function to get more granular hooks. function _validateBeforeTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _preValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _preValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _preValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Inheriting contracts should call this function in the _afterTokenTransfer function to get more granular hooks. function _validateAfterTransfer(address from, address to, uint256 tokenId) internal virtual { bool fromZeroAddress = from == address(0); bool toZeroAddress = to == address(0); if(fromZeroAddress && toZeroAddress) { revert ShouldNotMintToBurnAddress(); } else if(fromZeroAddress) { _postValidateMint(_msgSender(), to, tokenId, msg.value); } else if(toZeroAddress) { _postValidateBurn(_msgSender(), from, tokenId, msg.value); } else { _postValidateTransfer(_msgSender(), from, to, tokenId, msg.value); } } /// @dev Optional validation hook that fires before a mint function _preValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a mint function _postValidateMint(address caller, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a burn function _preValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a burn function _postValidateBurn(address caller, address from, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires before a transfer function _preValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} /// @dev Optional validation hook that fires after a transfer function _postValidateTransfer(address caller, address from, address to, uint256 tokenId, uint256 value) internal virtual {} }
@openzeppelin/contracts/utils/math/Math.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface VRFCoordinatorV2Interface { /** * @notice Get configuration relevant for making requests * @return minimumRequestConfirmations global min for request confirmations * @return maxGasLimit global max for request gas limit * @return s_provingKeyHashes list of registered key hashes */ function getRequestConfig() external view returns ( uint16, uint32, bytes32[] memory ); /** * @notice Request a set of random words. * @param keyHash - Corresponds to a particular oracle job which uses * that key for generating the VRF proof. Different keyHash's have different gas price * ceilings, so you can select a specific one to bound your maximum per request cost. * @param subId - The ID of the VRF subscription. Must be funded * with the minimum subscription balance required for the selected keyHash. * @param minimumRequestConfirmations - How many blocks you'd like the * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS * for why you may want to request more. The acceptable range is * [minimumRequestBlockConfirmations, 200]. * @param callbackGasLimit - How much gas you'd like to receive in your * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords * may be slightly less than this amount because of gas used calling the function * (argument decoding etc.), so you may need to request slightly more than you expect * to have inside fulfillRandomWords. The acceptable range is * [0, maxGasLimit] * @param numWords - The number of uint256 random values you'd like to receive * in your fulfillRandomWords callback. Note these numbers are expanded in a * secure way by the VRFCoordinator from a single random value supplied by the oracle. * @return requestId - A unique identifier of the request. Can be used to match * a request to a response in fulfillRandomWords. */ function requestRandomWords( bytes32 keyHash, uint64 subId, uint16 minimumRequestConfirmations, uint32 callbackGasLimit, uint32 numWords ) external returns (uint256 requestId); /** * @notice Create a VRF subscription. * @return subId - A unique subscription id. * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. * @dev Note to fund the subscription, use transferAndCall. For example * @dev LINKTOKEN.transferAndCall( * @dev address(COORDINATOR), * @dev amount, * @dev abi.encode(subId)); */ function createSubscription() external returns (uint64 subId); /** * @notice Get a VRF subscription. * @param subId - ID of the subscription * @return balance - LINK balance of the subscription in juels. * @return reqCount - number of requests for this subscription, determines fee tier. * @return owner - owner of the subscription. * @return consumers - list of consumer address which are able to use this subscription. */ function getSubscription(uint64 subId) external view returns ( uint96 balance, uint64 reqCount, address owner, address[] memory consumers ); /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @param newOwner - proposed new owner of the subscription */ function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external; /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @dev will revert if original owner of subId has * not requested that msg.sender become the new owner. */ function acceptSubscriptionOwnerTransfer(uint64 subId) external; /** * @notice Add a consumer to a VRF subscription. * @param subId - ID of the subscription * @param consumer - New consumer which can use the subscription */ function addConsumer(uint64 subId, address consumer) external; /** * @notice Remove a consumer from a VRF subscription. * @param subId - ID of the subscription * @param consumer - Consumer to remove from the subscription */ function removeConsumer(uint64 subId, address consumer) external; /** * @notice Cancel a subscription * @param subId - ID of the subscription * @param to - Where to send the remaining LINK to */ function cancelSubscription(uint64 subId, address to) external; /* * @notice Check to see if there exists a request commitment consumers * for all consumers and keyhashes for a given sub. * @param subId - ID of the subscription * @return true if there exists at least one unfulfilled request for the subscription, false * otherwise. */ function pendingRequestExists(uint64 subId) external view returns (bool); }
@openzeppelin/contracts/utils/Address.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
@limitbreak/creator-token-contracts/contracts/interfaces/ICreatorToken.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../interfaces/ICreatorTokenTransferValidator.sol"; interface ICreatorToken { event TransferValidatorUpdated(address oldValidator, address newValidator); function getTransferValidator() external view returns (ICreatorTokenTransferValidator); function getSecurityPolicy() external view returns (CollectionSecurityPolicy memory); function getWhitelistedOperators() external view returns (address[] memory); function getPermittedContractReceivers() external view returns (address[] memory); function isOperatorWhitelisted(address operator) external view returns (bool); function isContractReceiverPermitted(address receiver) external view returns (bool); function isTransferAllowed(address caller, address from, address to) external view returns (bool); }
@openzeppelin/contracts/token/ERC1155/IERC1155.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
contracts/interfaces/IValeriaBoosterPacks.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IValeriaBoosterPacks { event ItemDrops(address indexed to, uint256[] ids, uint256[] amounts); function moderatorMint( address account, uint256 id, uint256 amount, bytes memory data ) external; function moderatorMintBatch( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) external; function moderatorAirdrop( address[] memory tos, uint256[][] memory ids, uint256[][] memory amounts, bytes memory data ) external; function burnItem(address owner, uint256 typeId, uint256 amount) external; function burnItems( address owner, uint256[] memory typeIds, uint256[] memory amounts ) external; function mintItem(address to, uint256 typeId, uint256 amount) external; function mintItems( address to, uint256[] calldata typeIds, uint256[] calldata amounts ) external; function bulkSafeTransfer( uint256 typeId, uint256 amounts, address[] calldata recipients ) external; }
@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity ^0.8.0; import "../IERC1155.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. * * _Available since v3.1._ */ interface IERC1155MetadataURI is IERC1155 { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
@limitbreak/creator-token-contracts/contracts/interfaces/IEOARegistry.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface IEOARegistry is IERC165 { function isVerifiedEOA(address account) external view returns (bool); }
@limitbreak/creator-token-contracts/contracts/utils/TransferPolicy.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; enum AllowlistTypes { Operators, PermittedContractReceivers } enum ReceiverConstraints { None, NoCode, EOA } enum CallerConstraints { None, OperatorWhitelistEnableOTC, OperatorWhitelistDisableOTC } enum StakerConstraints { None, CallerIsTxOrigin, EOA } enum TransferSecurityLevels { Zero, One, Two, Three, Four, Five, Six } struct TransferSecurityPolicy { CallerConstraints callerConstraints; ReceiverConstraints receiverConstraints; } struct CollectionSecurityPolicy { TransferSecurityLevels transferSecurityLevel; uint120 operatorWhitelistId; uint120 permittedContractReceiversId; }
@openzeppelin/contracts/utils/introspection/ERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
@openzeppelin/contracts/access/IAccessControl.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":1000,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_boosterPacksContractAddress","internalType":"address"},{"type":"address","name":"_vrfV2Coordinator","internalType":"address"},{"type":"address","name":"_trustedForwarder","internalType":"address"},{"type":"bytes32","name":"keyHash_","internalType":"bytes32"},{"type":"uint64","name":"subscriptionId_","internalType":"uint64"},{"type":"string","name":"_uri","internalType":"string"},{"type":"address","name":"royaltyReceiver_","internalType":"address"},{"type":"uint96","name":"royaltyFeeNumerator_","internalType":"uint96"}]},{"type":"error","name":"CreatorTokenBase__InvalidTransferValidatorContract","inputs":[]},{"type":"error","name":"CreatorTokenBase__SetTransferValidatorFirst","inputs":[]},{"type":"error","name":"InvalidPackConfiguration","inputs":[]},{"type":"error","name":"IsPaused","inputs":[]},{"type":"error","name":"MaxPacksPerTransaction","inputs":[]},{"type":"error","name":"OnlyCoordinatorCanFulfill","inputs":[{"type":"address","name":"have","internalType":"address"},{"type":"address","name":"want","internalType":"address"}]},{"type":"error","name":"ShouldNotMintToBurnAddress","inputs":[]},{"type":"event","name":"ApprovalForAll","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"bool","name":"approved","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"DefaultRoyaltySet","inputs":[{"type":"address","name":"receiver","internalType":"address","indexed":true},{"type":"uint96","name":"feeNumerator","internalType":"uint96","indexed":false}],"anonymous":false},{"type":"event","name":"ItemDrops","inputs":[{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256[]","name":"ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"amounts","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"PackOpened","inputs":[{"type":"uint256","name":"requestId","internalType":"uint256","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"randomness","internalType":"uint256","indexed":false},{"type":"uint256","name":"packId","internalType":"uint256","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256[]","name":"tokenIds","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"RandomnessRequest","inputs":[{"type":"uint256","name":"requestId","internalType":"uint256","indexed":true},{"type":"uint256","name":"packId","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"RoleAdminChanged","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"previousAdminRole","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"newAdminRole","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"TokenRoyaltySet","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256","indexed":true},{"type":"address","name":"receiver","internalType":"address","indexed":true},{"type":"uint96","name":"feeNumerator","internalType":"uint96","indexed":false}],"anonymous":false},{"type":"event","name":"TransferBatch","inputs":[{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256[]","name":"ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"values","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"TransferSingle","inputs":[{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferValidatorUpdated","inputs":[{"type":"address","name":"oldValidator","internalType":"address","indexed":false},{"type":"address","name":"newValidator","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"URI","inputs":[{"type":"string","name":"value","internalType":"string","indexed":false},{"type":"uint256","name":"id","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DEFAULT_ADMIN_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint120","name":"","internalType":"uint120"}],"name":"DEFAULT_OPERATOR_WHITELIST_ID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"enum TransferSecurityLevels"}],"name":"DEFAULT_TRANSFER_SECURITY_LEVEL","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"DEFAULT_TRANSFER_VALIDATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"EXTERNAL_CONTRACT_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"MODERATOR_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"balanceOfBatch","inputs":[{"type":"address[]","name":"accounts","internalType":"address[]"},{"type":"uint256[]","name":"ids","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"bulkSafeTransfer","inputs":[{"type":"uint256","name":"typeId","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address[]","name":"recipients","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burnItem","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"uint256","name":"typeId","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burnItems","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"uint256[]","name":"typeIds","internalType":"uint256[]"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes[]","name":"","internalType":"bytes[]"}],"name":"configurationOf","inputs":[{"type":"uint256[]","name":"packIds","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"packId","internalType":"uint256"},{"type":"uint256","name":"quantity","internalType":"uint256"}],"name":"configurations","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getPermittedContractReceivers","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRoleAdmin","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct CollectionSecurityPolicy","components":[{"type":"uint8","name":"transferSecurityLevel","internalType":"enum TransferSecurityLevels"},{"type":"uint120","name":"operatorWhitelistId","internalType":"uint120"},{"type":"uint120","name":"permittedContractReceiversId","internalType":"uint120"}]}],"name":"getSecurityPolicy","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ICreatorTokenTransferValidator"}],"name":"getTransferValidator","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getWhitelistedOperators","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isApprovedForAll","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"address","name":"operator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isContractReceiverPermitted","inputs":[{"type":"address","name":"receiver","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isOperatorWhitelisted","inputs":[{"type":"address","name":"operator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPaused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isTransferAllowed","inputs":[{"type":"address","name":"caller","internalType":"address"},{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isTrustedForwarder","inputs":[{"type":"address","name":"forwarder","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"keyHash","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxPacksPerTx","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintItem","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"typeId","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintItems","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256[]","name":"typeIds","internalType":"uint256[]"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"moderatorAirdrop","inputs":[{"type":"address[]","name":"tos","internalType":"address[]"},{"type":"uint256[][]","name":"ids","internalType":"uint256[][]"},{"type":"uint256[][]","name":"amounts","internalType":"uint256[][]"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"moderatorMint","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"moderatorMintBatch","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256[]","name":"ids","internalType":"uint256[]"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"open","inputs":[{"type":"uint256","name":"packId","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rawFulfillRandomWords","inputs":[{"type":"uint256","name":"requestId","internalType":"uint256"},{"type":"uint256[]","name":"randomWords","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"royaltyInfo","inputs":[{"type":"uint256","name":"_tokenId","internalType":"uint256"},{"type":"uint256","name":"_salePrice","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeBatchTransferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256[]","name":"ids","internalType":"uint256[]"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setApprovalForAll","inputs":[{"type":"address","name":"operator","internalType":"address"},{"type":"bool","name":"approved","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBoosterPackContract","inputs":[{"type":"address","name":"_boosterPacksContractAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDefaultRoyalty","inputs":[{"type":"address","name":"receiver","internalType":"address"},{"type":"uint96","name":"feeNumerator","internalType":"uint96"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxPacksPerTransaction","inputs":[{"type":"uint256","name":"_maxPacksPerTx","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPackConfiguration","inputs":[{"type":"tuple","name":"config","internalType":"struct ValeriaLandBeforeTheWar.PackConfiguration","components":[{"type":"uint256","name":"packId","internalType":"uint256"},{"type":"uint256","name":"quantity","internalType":"uint256"},{"type":"uint256[]","name":"itemIds","internalType":"uint256[]"},{"type":"uint256[]","name":"probabilities","internalType":"uint256[]"},{"type":"uint256[]","name":"aliases","internalType":"uint256[]"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPaused","inputs":[{"type":"bool","name":"_isPaused","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setToCustomSecurityPolicy","inputs":[{"type":"uint8","name":"level","internalType":"enum TransferSecurityLevels"},{"type":"uint120","name":"operatorWhitelistId","internalType":"uint120"},{"type":"uint120","name":"permittedContractReceiversAllowlistId","internalType":"uint120"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setToCustomValidatorAndSecurityPolicy","inputs":[{"type":"address","name":"validator","internalType":"address"},{"type":"uint8","name":"level","internalType":"enum TransferSecurityLevels"},{"type":"uint120","name":"operatorWhitelistId","internalType":"uint120"},{"type":"uint120","name":"permittedContractReceiversAllowlistId","internalType":"uint120"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setToDefaultSecurityPolicy","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTokenRoyalty","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"},{"type":"uint96","name":"feeNumerator","internalType":"uint96"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTransferValidator","inputs":[{"type":"address","name":"transferValidator_","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTrustedForwarder","inputs":[{"type":"address","name":"newTrustedForwarder","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setURI","inputs":[{"type":"string","name":"_uri","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setUseVRF","inputs":[{"type":"bool","name":"_useVRF","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setVRFCallbackLimit","inputs":[{"type":"uint32","name":"_vrfGasLimit","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"subscriptionId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"uri","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"useVRF","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"vrfGasLimit","inputs":[]}]
Contract Creation Code
0x6101006040526009805461ffff60a01b1916600160a01b1790556014600b55600c805463ffffffff19166207a1201790553480156200003d57600080fd5b50604051620062183803806200621883398101604081905262000060916200042f565b868282888680620000718162000149565b50620000889050620000826200015b565b6200016c565b600680546001600160a01b0319166001600160a01b0392909216919091179055620000b48282620001be565b50506001600160a01b0316608052620000d86000620000d26200015b565b62000215565b620001077f71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834f620000d26200015b565b5050506001600160a01b0393841660a05260c0919091526001600160401b031660e05250600980546001600160a01b03191692909116919091179055620006e2565b600362000157828262000616565b5050565b600062000167620002b7565b905090565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620001ca8282620002df565b6040516001600160601b03821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000157576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620002736200015b565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6006546000906001600160a01b03163303620002da575060131936013560601c90565b503390565b6127106001600160601b0382161115620003535760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b60648201526084015b60405180910390fd5b6001600160a01b038216620003ab5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c69642072656365697665720000000000000060448201526064016200034a565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600755565b80516001600160a01b0381168114620003fc57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b80516001600160601b0381168114620003fc57600080fd5b600080600080600080600080610100898b0312156200044d57600080fd5b6200045889620003e4565b9750602062000469818b01620003e4565b97506200047960408b01620003e4565b60608b015160808c015191985096506001600160401b0380821682146200049f57600080fd5b60a08c015191965080821115620004b557600080fd5b818c0191508c601f830112620004ca57600080fd5b815181811115620004df57620004df62000401565b604051601f8201601f19908116603f011681019083821181831017156200050a576200050a62000401565b816040528281528f868487010111156200052357600080fd5b600093505b8284101562000547578484018601518185018701529285019262000528565b60008684830101528098505050505050506200056660c08a01620003e4565b91506200057660e08a0162000417565b90509295985092959890939650565b600181811c908216806200059a57607f821691505b602082108103620005bb57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000611576000816000526020600020601f850160051c81016020861015620005ec5750805b601f850160051c820191505b818110156200060d57828155600101620005f8565b5050505b505050565b81516001600160401b0381111562000632576200063262000401565b6200064a8162000643845462000585565b84620005c1565b602080601f831160018114620006825760008415620006695750858301515b600019600386901b1c1916600185901b1785556200060d565b600085815260208120601f198616915b82811015620006b35788860151825594840194600190910190840162000692565b5085821015620006d25787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e051615ae762000731600039600081816104fd015261128c015260008181610735015261126b01526000611244015260008181610cfd0152610d580152615ae76000f3fe608060405234801561001057600080fd5b50600436106103ea5760003560e01c80636c3b86991161021a578063c50b0d6311610135578063e5558d5e116100c8578063f2fde38b11610097578063f7c519a61161007c578063f7c519a614610a33578063f877a8af14610a46578063fd762d9214610a5957600080fd5b8063f2fde38b14610a0d578063f3154fa114610a2057600080fd5b8063e5558d5e14610998578063e985e9c5146109ab578063efd11b1e146109e7578063f242432a146109fa57600080fd5b8063d547741f11610104578063d547741f1461094c578063d6e7c1d91461095f578063da74222814610972578063db28d3a81461098557600080fd5b8063c50b0d63146108f7578063d007af5c1461091e578063d07f824714610926578063d25815351461093957600080fd5b806395d89b41116101ad578063a9fc664e1161017c578063a9fc664e14610896578063b187bd26146108a9578063be537f43146108bd578063bf7d8146146108d257600080fd5b806395d89b411461082f5780639d645a4414610868578063a217fddf1461087b578063a22cb4651461088357600080fd5b80638749e26f116101e95780638749e26f146107985780638d85c96f146107d45780638da5cb5b146107e757806391d14854146107f857600080fd5b80636c3b86991461076a578063715018a614610772578063797669c91461077a5780638307b56e1461078f57600080fd5b80632e8da8291161030a5780634e1273f41161029d5780635d4c1d461161026c5780635d4c1d46146106fd578063613471621461071d57806361728f3914610730578063696a50b41461075757600080fd5b80634e1273f414610688578063572b6c05146106a857806357455bcb146106ca5780635944c753146106ea57600080fd5b80634082de67116102d95780634082de671461063a57806341f7a0b81461064d578063495c8bf9146106605780634a1e31e81461067557600080fd5b80632e8da829146105ee5780632eb2c2d6146106015780632f2ff15d1461061457806336568abe1461062757600080fd5b806309c1ba2e116103825780631c33b328116103515780631c33b328146105715780631fe543e314610586578063248a9ca3146105995780632a55205a146105bc57600080fd5b806309c1ba2e146104f85780630e89341c1461053857806316c38b3c1461054b5780631b25b0771461055e57600080fd5b806304634d8d116103be57806304634d8d1461047e578063060383411461049157806306fdde03146104a5578063098144d4146104e757600080fd5b8062fdd58e146103ef578063014635461461041557806301ffc9a71461044657806302fe530514610469575b600080fd5b6104026103fd366004614690565b610a6c565b6040519081526020015b60405180910390f35b61042e71721c310194ccfc01e523fc93c9cccfa2a0ac81565b6040516001600160a01b03909116815260200161040c565b6104596104543660046146d2565b610b1a565b604051901515815260200161040c565b61047c610477366004614790565b610b25565b005b61047c61048c366004614802565b610b4a565b60095461045990600160a81b900460ff1681565b60408051808201909152601c81527f56616c657269613a204c616e64204265666f726520546865205761720000000060208201525b60405161040c9190614887565b6004546001600160a01b031661042e565b61051f7f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff909116815260200161040c565b6104da61054636600461489a565b610b71565b61047c6105593660046148c1565b610c05565b61045961056c3660046148de565b610c57565b610579600181565b60405161040c919061494b565b61047c6105943660046149f3565b610cf2565b6104026105a736600461489a565b60009081526020819052604090206001015490565b6105cf6105ca366004614a3a565b610d8f565b604080516001600160a01b03909316835260208301919091520161040c565b6104596105fc366004614a5c565b610e4c565b61047c61060f366004614a99565b610f59565b61047c610622366004614b47565b61100d565b61047c610635366004614b47565b611032565b61047c610648366004614a3a565b6110ca565b61047c61065b366004614bbc565b611512565b610668611681565b60405161040c9190614c7a565b61047c610683366004614cc7565b611793565b61069b610696366004614d1a565b6117ef565b60405161040c9190614e19565b6104596106b6366004614a5c565b6006546001600160a01b0391821691161490565b6106dd6106d8366004614e2c565b611925565b60405161040c9190614e61565b61047c6106f8366004614ec5565b611a17565b610705600181565b6040516001600160781b03909116815260200161040c565b61047c61072b366004614f25565b611a40565b6104027f000000000000000000000000000000000000000000000000000000000000000081565b61047c610765366004614f65565b611bd5565b61047c611c1a565b61047c611d0c565b610402600080516020615a9283398151915281565b610402600b5481565b6107bf6107a636600461489a565b600e602052600090815260409020805460019091015482565b6040805192835260208301919091520161040c565b61047c6107e2366004614f9a565b611d20565b6005546001600160a01b031661042e565b610459610806366004614b47565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60408051808201909152600681527f56414c425457000000000000000000000000000000000000000000000000000060208201526104da565b610459610876366004614a5c565b611dce565b610402600081565b61047c61089136600461501d565b611e97565b61047c6108a4366004614a5c565b611ea9565b60095461045990600160a01b900460ff1681565b6108c5611fe3565b60405161040c919061504b565b600c546108e29063ffffffff1681565b60405163ffffffff909116815260200161040c565b6104027ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce86081565b61066861209f565b61047c610934366004615087565b612159565b61047c610947366004614f65565b61218e565b61047c61095a366004614b47565b6121c3565b61047c61096d3660046150ad565b6121e8565b61047c610980366004614a5c565b61235f565b61047c610993366004614a5c565b612389565b61047c6109a63660046150e8565b6123c4565b6104596109b936600461518d565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b61047c6109f536600461489a565b612455565b61047c610a083660046151bb565b612473565b61047c610a1b366004614a5c565b612520565b61047c610a2e366004615224565b6125b0565b61047c610a41366004614f9a565b6125d4565b61047c610a543660046148c1565b61266c565b61047c610a67366004615287565b6126be565b60006001600160a01b038316610aef5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e65720000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526001602090815260408083206001600160a01b03861684529091529020545b92915050565b6000610b14826127d2565b600080516020615a92833981519152610b3d81612810565b610b4682612821565b5050565b600080516020615a92833981519152610b6281612810565b610b6c838361282d565b505050565b606060038054610b80906152e3565b80601f0160208091040260200160405190810160405280929190818152602001828054610bac906152e3565b8015610bf95780601f10610bce57610100808354040283529160200191610bf9565b820191906000526020600020905b815481529060010190602001808311610bdc57829003601f168201915b50505050509050919050565b600080516020615a92833981519152610c1d81612810565b5060098054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6004546000906001600160a01b031615610ce7576004805460405163050bf71960e31b81526001600160a01b03878116938201939093528583166024820152848316604482015291169063285fb8c89060640160006040518083038186803b158015610cc257600080fd5b505afa925050508015610cd3575060015b610cdf57506000610ceb565b506001610ceb565b5060015b9392505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610d85576040517f1cf993f40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610ae6565b610b468282612887565b60008281526008602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046bffffffffffffffffffffffff16928201929092528291610e0e5750604080518082019091526007546001600160a01b0381168252600160a01b90046bffffffffffffffffffffffff1660208201525b602081015160009061271090610e32906bffffffffffffffffffffffff1687615333565b610e3c9190615360565b91519350909150505b9250929050565b6004546000906001600160a01b031615610f515760048054604051635caaa2a960e11b815230928101929092526001600160a01b03169063d72dde5e90829063b955455290602401606060405180830381865afa158015610eb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed59190615374565b602001516040516001600160e01b031960e084901b1681526001600160781b0390911660048201526001600160a01b03851660248201526044015b602060405180830381865afa158015610f2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1491906153e6565b506000919050565b610f616128ab565b6001600160a01b0316856001600160a01b03161480610f875750610f87856109b96128ab565b610ff95760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f7665640000000000000000000000000000000000006064820152608401610ae6565b61100685858585856128b5565b5050505050565b60008281526020819052604090206001015461102881612810565b610b6c8383612b2e565b61103a6128ab565b6001600160a01b0316816001600160a01b0316146110c05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610ae6565b610b468282612bcd565b600954600160a01b900460ff161561110e576040517f1309a56300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b5481111561114a576040517f69a1c3a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600e6020526040902080548314611192576040517f3a02e7f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061119c6128ab565b6009546040517fd25815350000000000000000000000000000000000000000000000000000000081526001600160a01b038084166004830152602482018890526044820187905292935091169063d258153590606401600060405180830381600087803b15801561120c57600080fd5b505af1158015611220573d6000803e3d6000fd5b505060095460009250600160a81b900460ff1615905061137a576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016635d3b1d307f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000600c5460405160e085901b6001600160e01b0319168152600481019390935267ffffffffffffffff90911660248301526003604483015263ffffffff1660648201526001608482015260a4016020604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133a9190615403565b905061134881868685612c6a565b604051859082907fbd6dfba7e9a62090fe5538754d1d033d2710db089fe446d1555e343bcd35717490600090a3611006565b600a805490600061138a8361541c565b9190505550611006600a54600e60008881526020019081526020016000206040518060a001604052908160008201548152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561141657602002820191906000526020600020905b815481526020019060010190808311611402575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561146e57602002820191906000526020600020905b81548152602001906001019080831161145a575b50505050508152602001600482018054806020026020016040519081016040528092919081815260200182805480156114c657602002820191906000526020600020905b8154815260200190600101908083116114b2575b50505050508152505061150b600a5460408051426020808301919091524482840152606080830194909452825180830390940184526080909101909152815191012090565b8786612cc6565b600080516020615a9283398151915261152a81612810565b868514801561153857508483145b6115845760405162461bcd60e51b815260206004820152600660248201527f2176616c696400000000000000000000000000000000000000000000000000006044820152606401610ae6565b60005b878110156116765761166e8989838181106115a4576115a4615435565b90506020020160208101906115b99190614a5c565b8888848181106115cb576115cb615435565b90506020028101906115dd919061544b565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a925089915086905081811061162357611623615435565b9050602002810190611635919061544b565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612e1b915050565b600101611587565b505050505050505050565b6004546060906001600160a01b0316156117805760048054604051635caaa2a960e11b815230928101929092526001600160a01b031690633fe5df9990829063b955455290602401606060405180830381865afa1580156116e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170a9190615374565b602001516040516001600160e01b031960e084901b1681526001600160781b0390911660048201526024015b600060405180830381865afa158015611753573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261177b9190810190615495565b905090565b5060408051600081526020810190915290565b60005b81811015611006576117e76117a96128ab565b8484848181106117bb576117bb615435565b90506020020160208101906117d09190614a5c565b878760405180602001604052806000815250612473565b600101611796565b606081518351146118685760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152608401610ae6565b6000835167ffffffffffffffff811115611884576118846146ef565b6040519080825280602002602001820160405280156118ad578160200160208202803683370190505b50905060005b845181101561191d576118f88582815181106118d1576118d1615435565b60200260200101518583815181106118eb576118eb615435565b6020026020010151610a6c565b82828151811061190a5761190a615435565b60209081029190910101526001016118b3565b509392505050565b60606000825167ffffffffffffffff811115611943576119436146ef565b60405190808252806020026020018201604052801561197657816020015b60608152602001906001900390816119615790505b50905060008060005b8551811015611a0d5785818151811061199a5761199a615435565b60200260200101519150600e6000838152602001908152602001600020925082600001548360010154846002016040516020016119d99392919061553a565b6040516020818303038152906040528482815181106119fa576119fa615435565b602090810291909101015260010161197f565b5091949350505050565b600080516020615a92833981519152611a2f81612810565b611a3a848484613000565b50505050565b611a4861305f565b6000611a5c6004546001600160a01b031690565b90506001600160a01b038116611a9e576040517f39ffc7ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051630368065360e61b81526001600160a01b0382169063da0194c090611acc9030908890600401615596565b600060405180830381600087803b158015611ae657600080fd5b505af1158015611afa573d6000803e3d6000fd5b5050604051631182550160e11b81523060048201526001600160781b03861660248201526001600160a01b0384169250632304aa029150604401600060405180830381600087803b158015611b4e57600080fd5b505af1158015611b62573d6000803e3d6000fd5b505060405163235d10c560e21b81523060048201526001600160781b03851660248201526001600160a01b0384169250638d74431491506044015b600060405180830381600087803b158015611bb757600080fd5b505af1158015611bcb573d6000803e3d6000fd5b5050505050505050565b7ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce860611bff81612810565b611a3a84848460405180602001604052806000815250613076565b611c2261305f565b611c3d71721c310194ccfc01e523fc93c9cccfa2a0ac611ea9565b604051630368065360e61b815271721c310194ccfc01e523fc93c9cccfa2a0ac9063da0194c090611c75903090600190600401615596565b600060405180830381600087803b158015611c8f57600080fd5b505af1158015611ca3573d6000803e3d6000fd5b5050604051631182550160e11b81523060048201526001602482015271721c310194ccfc01e523fc93c9cccfa2a0ac9250632304aa029150604401600060405180830381600087803b158015611cf857600080fd5b505af1158015611a3a573d6000803e3d6000fd5b611d146131ac565b611d1e6000613225565b565b7ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce860611d4a81612810565b611dc68686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092018290525060408051602081019091529081529250612e1b915050565b505050505050565b6004546000906001600160a01b031615610f515760048054604051635caaa2a960e11b815230928101929092526001600160a01b031690639445f53090829063b955455290602401606060405180830381865afa158015611e33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e579190615374565b60409081015190516001600160e01b031960e084901b1681526001600160781b0390911660048201526001600160a01b0385166024820152604401610f10565b610b46611ea26128ab565b8383613277565b611eb161305f565b60006001600160a01b0382163b15611f2c576040516301ffc9a760e01b8152600060048201526001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015611f24575060408051601f3d908101601f19168201909252611f21918101906153e6565b60015b15611f2c5790505b6001600160a01b03821615801590611f42575080155b15611f79576040517f32483afb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454604080516001600160a01b03928316815291841660208301527fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac910160405180910390a150600480546001600160a01b0319166001600160a01b0392909216919091179055565b60408051606081018252600080825260208201819052918101919091526004546001600160a01b03161561207e5760048054604051635caaa2a960e11b815230928101929092526001600160a01b03169063b955455290602401606060405180830381865afa15801561205a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177b9190615374565b50604080516060810182526000808252602082018190529181019190915290565b6004546060906001600160a01b0316156117805760048054604051635caaa2a960e11b815230928101929092526001600160a01b0316906317e94a6c90829063b955455290602401606060405180830381865afa158015612104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121289190615374565b60409081015190516001600160e01b031960e084901b1681526001600160781b039091166004820152602401611736565b600080516020615a9283398151915261217181612810565b50600c805463ffffffff191663ffffffff92909216919091179055565b7ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce8606121b881612810565b611a3a848484613363565b6000828152602081905260409020600101546121de81612810565b610b6c8383612bcd565b600080516020615a9283398151915261220081612810565b600082602001351161227a5760405162461bcd60e51b815260206004820152602660248201527f4d696e74207175616e746974792073686f756c6420626520677265617465722060448201527f7468616e203000000000000000000000000000000000000000000000000000006064820152608401610ae6565b6000612289604084018461544b565b9050116122d85760405162461bcd60e51b815260206004820152601960248201527f4d7573742068617665206174206c656173742031206974656d000000000000006044820152606401610ae6565b6122e5608083018361544b565b90506122f4606084018461544b565b9050146123435760405162461bcd60e51b815260206004820152600e60248201527f496e76616c696420636f6e6669670000000000000000000000000000000000006044820152606401610ae6565b81356000908152600e602052604090208290611a3a8282615648565b6123676131ac565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b600080516020615a928339815191526123a181612810565b50600980546001600160a01b0319166001600160a01b0392909216919091179055565b600080516020615a928339815191526123dc81612810565b61244c8787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250612e1b915050565b50505050505050565b600080516020615a9283398151915261246d81612810565b50600b55565b61247b6128ab565b6001600160a01b0316856001600160a01b031614806124a157506124a1856109b96128ab565b6125135760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f7665640000000000000000000000000000000000006064820152608401610ae6565b611006858585858561350c565b6125286131ac565b6001600160a01b0381166125a45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610ae6565b6125ad81613225565b50565b600080516020615a928339815191526125c881612810565b61100685858585613076565b7ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce8606125fe81612810565b611dc68686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808a028281018201909352898252909350899250889182918501908490808284376000920191909152506136d792505050565b600080516020615a9283398151915261268481612810565b5060098054911515600160a81b027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff909216919091179055565b6126c661305f565b6126cf84611ea9565b604051630368065360e61b81526001600160a01b0385169063da0194c0906126fd9030908790600401615596565b600060405180830381600087803b15801561271757600080fd5b505af115801561272b573d6000803e3d6000fd5b5050604051631182550160e11b81523060048201526001600160781b03851660248201526001600160a01b0387169250632304aa029150604401600060405180830381600087803b15801561277f57600080fd5b505af1158015612793573d6000803e3d6000fd5b505060405163235d10c560e21b81523060048201526001600160781b03841660248201526001600160a01b0387169250638d7443149150604401611b9d565b60006001600160e01b031982167f2a55205a000000000000000000000000000000000000000000000000000000001480610b145750610b1482613935565b6125ad8161281c6128ab565b613973565b6003610b46828261575d565b61283782826139e6565b6040516bffffffffffffffffffffffff821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b610b46828260008151811061289e5761289e615435565b6020026020010151613aed565b600061177b613af7565b81518351146129175760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610ae6565b6001600160a01b03841661297b5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610ae6565b60006129856128ab565b9050612995818787878787613b21565b60005b8451811015612aba5760008582815181106129b5576129b5615435565b6020026020010151905060008583815181106129d3576129d3615435565b60209081029190910181015160008481526001835260408082206001600160a01b038e168352909352919091205490915081811015612a675760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608401610ae6565b60008381526001602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290612aa690849061581d565b909155505060019093019250612998915050565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612b0a929190615830565b60405180910390a4612b20818787878787613b5a565b611dc6818787878787613b93565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610b46576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055612b896128ab565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610b46576000828152602081815260408083206001600160a01b03851684529091529020805460ff19169055612c266128ab565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b611a3a84848484604080516060810182526001600160a01b03928316815260208082019586528183019485526000968752600d905294209351845491166001600160a01b03199091161783559051600183015551600290910155565b6000828560200151612cd89190615333565b905060008167ffffffffffffffff811115612cf557612cf56146ef565b604051908082528060200260200182016040528015612d1e578160200160208202803683370190505b50905060008060005b84811015612db957640100000000612d4082600161581d565b612d4b90600a615333565b612d55908a615360565b612d5f919061585e565b9250612d74838a606001518b60800151613d38565b915088604001518281518110612d8c57612d8c615435565b6020026020010151848281518110612da657612da6615435565b6020908102919091010152600101612d27565b612dc38685613da4565b856001600160a01b03168a7fb8886e73a6f3f585c87b51e4888e9cdcc0e915f6f4f0a1e410c722ce0398240b8a8c600001518989604051612e079493929190615872565b60405180910390a350505050505050505050565b6001600160a01b038416612e7b5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610ae6565b8151835114612edd5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610ae6565b6000612ee76128ab565b9050612ef881600087878787613b21565b60005b8451811015612f8957838181518110612f1657612f16615435565b602002602001015160016000878481518110612f3457612f34615435565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254612f7c919061581d565b9091555050600101612efb565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612fda929190615830565b60405180910390a4612ff181600087878787613b5a565b61100681600087878787613b93565b61300b838383613eba565b6040516bffffffffffffffffffffffff821681526001600160a01b0383169084907f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c906020015b60405180910390a3505050565b611d1e600080516020615a92833981519152612810565b6001600160a01b0384166130d65760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610ae6565b60006130e06128ab565b905060006130ed85613fd2565b905060006130fa85613fd2565b905061310b83600089858589613b21565b60008681526001602090815260408083206001600160a01b038b1684529091528120805487929061313d90849061581d565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461319d83600089858589613b5a565b61244c8360008989898961401d565b6131b46128ab565b6001600160a01b03166131cf6005546001600160a01b031690565b6001600160a01b031614611d1e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ae6565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b0316036132fe5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c6600000000000000000000000000000000000000000000006064820152608401610ae6565b6001600160a01b03838116600081815260026020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319101613052565b6001600160a01b0383166133c55760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608401610ae6565b60006133cf6128ab565b905060006133dc84613fd2565b905060006133e984613fd2565b905061340983876000858560405180602001604052806000815250613b21565b60008581526001602090815260408083206001600160a01b038a168452909152902054848110156134885760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608401610ae6565b60008681526001602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461244c84886000868660405180602001604052806000815250613b5a565b6001600160a01b0384166135705760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610ae6565b600061357a6128ab565b9050600061358785613fd2565b9050600061359485613fd2565b90506135a4838989858589613b21565b60008681526001602090815260408083206001600160a01b038c1684529091529020548581101561362a5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608401610ae6565b60008781526001602090815260408083206001600160a01b038d8116855292528083208985039055908a1682528120805488929061366990849061581d565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46136c9848a8a86868a613b5a565b611676848a8a8a8a8a61401d565b6001600160a01b0383166137395760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608401610ae6565b805182511461379b5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610ae6565b60006137a56128ab565b90506137c581856000868660405180602001604052806000815250613b21565b60005b83518110156138be5760008482815181106137e5576137e5615435565b60200260200101519050600084838151811061380357613803615435565b60209081029190910181015160008481526001835260408082206001600160a01b038c1683529093529190912054909150818110156138905760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608401610ae6565b60009283526001602081815260408086206001600160a01b038c1687529091529093209190039055016137c8565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb868660405161390f929190615830565b60405180910390a4611a3a81856000868660405180602001604052806000815250613b5a565b60006001600160e01b031982167f86455d28000000000000000000000000000000000000000000000000000000001480610b145750610b1482614119565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610b46576139a48161418b565b6139af83602061419d565b6040516020016139c09291906158a1565b60408051601f198184030181529082905262461bcd60e51b8252610ae691600401614887565b6127106bffffffffffffffffffffffff82161115613a595760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610ae6565b6001600160a01b038216613aaf5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610ae6565b604080518082019091526001600160a01b039092168083526bffffffffffffffffffffffff9091166020909201829052600160a01b90910217600755565b610b46828261437e565b6006546000906001600160a01b03163303613b19575060131936013560601c90565b503390565b90565b825160005b81811015611bcb57613b528787878481518110613b4557613b45615435565b60200260200101516144d9565b600101613b26565b825160005b81811015611bcb57613b8b8787878481518110613b7e57613b7e615435565b602002602001015161454c565b600101613b5f565b6001600160a01b0384163b15611dc65760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190613bd79089908990889088908890600401615922565b6020604051808303816000875af1925050508015613c12575060408051601f3d908101601f19168201909252613c0f91810190615980565b60015b613cc757613c1e61599d565b806308c379a003613c575750613c326159b8565b80613c3d5750613c59565b8060405162461bcd60e51b8152600401610ae69190614887565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608401610ae6565b6001600160e01b0319811663bc197c8160e01b1461244c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b6064820152608401610ae6565b815160009061ffff8516908290613d4f908361585e565b9050848181518110613d6357613d63615435565b6020026020010151600883901c1015613d7f579150610ceb9050565b838181518110613d9157613d91615435565b6020026020010151925050509392505050565b805160008167ffffffffffffffff811115613dc157613dc16146ef565b604051908082528060200260200182016040528015613dea578160200160208202803683370190505b50905060008267ffffffffffffffff811115613e0857613e086146ef565b604051908082528060200260200182016040528015613e31578160200160208202803683370190505b50905060005b83811015613e9e57848181518110613e5157613e51615435565b6020026020010151838281518110613e6b57613e6b615435565b6020026020010181815250506001828281518110613e8b57613e8b615435565b6020908102919091010152600101613e37565b5061100685838360405180602001604052806000815250612e1b565b6127106bffffffffffffffffffffffff82161115613f2d5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610ae6565b6001600160a01b038216613f835760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610ae6565b6040805180820182526001600160a01b0393841681526bffffffffffffffffffffffff92831660208083019182526000968752600890529190942093519051909116600160a01b029116179055565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061400c5761400c615435565b602090810291909101015292915050565b6001600160a01b0384163b15611dc65760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906140619089908990889088908890600401615a42565b6020604051808303816000875af192505050801561409c575060408051601f3d908101601f1916820190925261409991810190615980565b60015b6140a857613c1e61599d565b6001600160e01b0319811663f23a6e6160e01b1461244c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b6064820152608401610ae6565b60006001600160e01b031982167fd9b67a2600000000000000000000000000000000000000000000000000000000148061417c57506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b80610b145750610b14826145b1565b6060610b146001600160a01b03831660145b606060006141ac836002615333565b6141b790600261581d565b67ffffffffffffffff8111156141cf576141cf6146ef565b6040519080825280601f01601f1916602001820160405280156141f9576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061423057614230615435565b60200101906001600160f81b031916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061427b5761427b615435565b60200101906001600160f81b031916908160001a905350600061429f846002615333565b6142aa90600161581d565b90505b600181111561432f577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106142eb576142eb615435565b1a60f81b82828151811061430157614301615435565b60200101906001600160f81b031916908160001a90535060049490941c9361432881615a7a565b90506142ad565b508315610ceb5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ae6565b6000828152600d602090815260408083206001808201548552600e845293829020825160a08101845281548152948101548585015260028101805484518187028101870186528181529396610b6c968a9691959186019391929083018282801561440757602002820191906000526020600020905b8154815260200190600101908083116143f3575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561445f57602002820191906000526020600020905b81548152602001906001019080831161444b575b50505050508152602001600482018054806020026020016040519081016040528092919081815260200182805480156144b757602002820191906000526020600020905b8154815260200190600101908083116144a3575b50505091909252505050600284015484548691906001600160a01b0316612cc6565b6001600160a01b0383811615908316158180156144f35750805b1561451157604051635cbd944160e01b815260040160405180910390fd5b8115614527576145226125ad6128ab565b611006565b8015614538576145226125ad6128ab565b6110066145436128ab565b868686346145ff565b6001600160a01b0383811615908316158180156145665750805b1561458457604051635cbd944160e01b815260040160405180910390fd5b8115614595576145226125ad6128ab565b80156145a6576145226125ad6128ab565b6110066125ad6128ab565b60006001600160e01b031982167f7965db0b000000000000000000000000000000000000000000000000000000001480610b1457506301ffc9a760e01b6001600160e01b0319831614610b14565b6004546001600160a01b031615611006576004805460405163050bf71960e31b81526001600160a01b03888116938201939093528683166024820152858316604482015291169063285fb8c89060640160006040518083038186803b15801561466757600080fd5b505afa158015611676573d6000803e3d6000fd5b6001600160a01b03811681146125ad57600080fd5b600080604083850312156146a357600080fd5b82356146ae8161467b565b946020939093013593505050565b6001600160e01b0319811681146125ad57600080fd5b6000602082840312156146e457600080fd5b8135610ceb816146bc565b634e487b7160e01b600052604160045260246000fd5b601f8201601f1916810167ffffffffffffffff8111828210171561472b5761472b6146ef565b6040525050565b600067ffffffffffffffff83111561474c5761474c6146ef565b604051614763601f8501601f191660200182614705565b80915083815284848401111561477857600080fd5b83836020830137600060208583010152509392505050565b6000602082840312156147a257600080fd5b813567ffffffffffffffff8111156147b957600080fd5b8201601f810184136147ca57600080fd5b6147d984823560208401614732565b949350505050565b80356bffffffffffffffffffffffff811681146147fd57600080fd5b919050565b6000806040838503121561481557600080fd5b82356148208161467b565b915061482e602084016147e1565b90509250929050565b60005b8381101561485257818101518382015260200161483a565b50506000910152565b60008151808452614873816020860160208601614837565b601f01601f19169290920160200192915050565b602081526000610ceb602083018461485b565b6000602082840312156148ac57600080fd5b5035919050565b80151581146125ad57600080fd5b6000602082840312156148d357600080fd5b8135610ceb816148b3565b6000806000606084860312156148f357600080fd5b83356148fe8161467b565b9250602084013561490e8161467b565b9150604084013561491e8161467b565b809150509250925092565b6007811061494757634e487b7160e01b600052602160045260246000fd5b9052565b60208101610b148284614929565b600067ffffffffffffffff821115614973576149736146ef565b5060051b60200190565b600082601f83011261498e57600080fd5b8135602061499b82614959565b6040516149a88282614705565b80915083815260208101915060208460051b8701019350868411156149cc57600080fd5b602086015b848110156149e857803583529183019183016149d1565b509695505050505050565b60008060408385031215614a0657600080fd5b82359150602083013567ffffffffffffffff811115614a2457600080fd5b614a308582860161497d565b9150509250929050565b60008060408385031215614a4d57600080fd5b50508035926020909101359150565b600060208284031215614a6e57600080fd5b8135610ceb8161467b565b600082601f830112614a8a57600080fd5b610ceb83833560208501614732565b600080600080600060a08688031215614ab157600080fd5b8535614abc8161467b565b94506020860135614acc8161467b565b9350604086013567ffffffffffffffff80821115614ae957600080fd5b614af589838a0161497d565b94506060880135915080821115614b0b57600080fd5b614b1789838a0161497d565b93506080880135915080821115614b2d57600080fd5b50614b3a88828901614a79565b9150509295509295909350565b60008060408385031215614b5a57600080fd5b823591506020830135614b6c8161467b565b809150509250929050565b60008083601f840112614b8957600080fd5b50813567ffffffffffffffff811115614ba157600080fd5b6020830191508360208260051b8501011115610e4557600080fd5b60008060008060008060006080888a031215614bd757600080fd5b873567ffffffffffffffff80821115614bef57600080fd5b614bfb8b838c01614b77565b909950975060208a0135915080821115614c1457600080fd5b614c208b838c01614b77565b909750955060408a0135915080821115614c3957600080fd5b614c458b838c01614b77565b909550935060608a0135915080821115614c5e57600080fd5b50614c6b8a828b01614a79565b91505092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015614cbb5783516001600160a01b031683529284019291840191600101614c96565b50909695505050505050565b60008060008060608587031215614cdd57600080fd5b8435935060208501359250604085013567ffffffffffffffff811115614d0257600080fd5b614d0e87828801614b77565b95989497509550505050565b60008060408385031215614d2d57600080fd5b823567ffffffffffffffff80821115614d4557600080fd5b818501915085601f830112614d5957600080fd5b81356020614d6682614959565b604051614d738282614705565b83815260059390931b8501820192828101915089841115614d9357600080fd5b948201945b83861015614dba578535614dab8161467b565b82529482019490820190614d98565b96505086013592505080821115614dd057600080fd5b50614a308582860161497d565b60008151808452602080850194506020840160005b83811015614e0e57815187529582019590820190600101614df2565b509495945050505050565b602081526000610ceb6020830184614ddd565b600060208284031215614e3e57600080fd5b813567ffffffffffffffff811115614e5557600080fd5b6147d98482850161497d565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614eb857603f19888603018452614ea685835161485b565b94509285019290850190600101614e8a565b5092979650505050505050565b600080600060608486031215614eda57600080fd5b833592506020840135614eec8161467b565b9150614efa604085016147e1565b90509250925092565b600781106125ad57600080fd5b6001600160781b03811681146125ad57600080fd5b600080600060608486031215614f3a57600080fd5b8335614f4581614f03565b92506020840135614f5581614f10565b9150604084013561491e81614f10565b600080600060608486031215614f7a57600080fd5b8335614f858161467b565b95602085013595506040909401359392505050565b600080600080600060608688031215614fb257600080fd5b8535614fbd8161467b565b9450602086013567ffffffffffffffff80821115614fda57600080fd5b614fe689838a01614b77565b90965094506040880135915080821115614fff57600080fd5b5061500c88828901614b77565b969995985093965092949392505050565b6000806040838503121561503057600080fd5b823561503b8161467b565b91506020830135614b6c816148b3565b600060608201905061505e828451614929565b60208301516001600160781b038082166020850152806040860151166040850152505092915050565b60006020828403121561509957600080fd5b813563ffffffff81168114610ceb57600080fd5b6000602082840312156150bf57600080fd5b813567ffffffffffffffff8111156150d657600080fd5b820160a08185031215610ceb57600080fd5b6000806000806000806080878903121561510157600080fd5b863561510c8161467b565b9550602087013567ffffffffffffffff8082111561512957600080fd5b6151358a838b01614b77565b9097509550604089013591508082111561514e57600080fd5b61515a8a838b01614b77565b9095509350606089013591508082111561517357600080fd5b5061518089828a01614a79565b9150509295509295509295565b600080604083850312156151a057600080fd5b82356151ab8161467b565b91506020830135614b6c8161467b565b600080600080600060a086880312156151d357600080fd5b85356151de8161467b565b945060208601356151ee8161467b565b93506040860135925060608601359150608086013567ffffffffffffffff81111561521857600080fd5b614b3a88828901614a79565b6000806000806080858703121561523a57600080fd5b84356152458161467b565b93506020850135925060408501359150606085013567ffffffffffffffff81111561526f57600080fd5b61527b87828801614a79565b91505092959194509250565b6000806000806080858703121561529d57600080fd5b84356152a88161467b565b935060208501356152b881614f03565b925060408501356152c881614f10565b915060608501356152d881614f10565b939692955090935050565b600181811c908216806152f757607f821691505b60208210810361531757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610b1457610b1461531d565b634e487b7160e01b600052601260045260246000fd5b60008261536f5761536f61534a565b500490565b60006060828403121561538657600080fd5b6040516060810181811067ffffffffffffffff821117156153a9576153a96146ef565b60405282516153b781614f03565b815260208301516153c781614f10565b602082015260408301516153da81614f10565b60408201529392505050565b6000602082840312156153f857600080fd5b8151610ceb816148b3565b60006020828403121561541557600080fd5b5051919050565b60006001820161542e5761542e61531d565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261546257600080fd5b83018035915067ffffffffffffffff82111561547d57600080fd5b6020019150600581901b3603821315610e4557600080fd5b600060208083850312156154a857600080fd5b825167ffffffffffffffff8111156154bf57600080fd5b8301601f810185136154d057600080fd5b80516154db81614959565b6040516154e88282614705565b82815260059290921b830184019184810191508783111561550857600080fd5b928401925b8284101561552f5783516155208161467b565b8252928401929084019061550d565b979650505050505050565b600060608201858352602085602085015260606040850152818554808452608086019150866000526020600020935060005b818110156155885784548352600194850194928401920161556c565b509098975050505050505050565b6001600160a01b038316815260408101610ceb6020830184614929565b5b81811015610b4657600081556001016155b4565b67ffffffffffffffff8311156155e0576155e06146ef565b680100000000000000008311156155f9576155f96146ef565b80548382558084101561561f5781600052602060002061561d8282018683016155b3565b505b50818160005260208060002060005b8681101561244c578335828201559282019260010161562e565b81358155600160208084013560018401556002830161566a604086018661544b565b67ffffffffffffffff811115615682576156826146ef565b6801000000000000000081111561569b5761569b6146ef565b8254818455808210156156c1578360005260206000206156bf8282018483016155b3565b505b50600092835260208320925b818110156156e6578235848201559184019185016156cd565b5050505050506156f9606083018361544b565b6157078183600386016155c8565b5050615716608083018361544b565b611a3a8183600486016155c8565b601f821115610b6c57806000526020600020601f840160051c8101602085101561574b5750805b611006601f850160051c8301826155b3565b815167ffffffffffffffff811115615777576157776146ef565b61578b8161578584546152e3565b84615724565b602080601f8311600181146157c057600084156157a85750858301515b600019600386901b1c1916600185901b178555611dc6565b600085815260208120601f198616915b828110156157ef578886015182559484019460019091019084016157d0565b508582101561580d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80820180821115610b1457610b1461531d565b6040815260006158436040830185614ddd565b82810360208401526158558185614ddd565b95945050505050565b60008261586d5761586d61534a565b500690565b8481528360208201528260408201526080606082015260006158976080830184614ddd565b9695505050505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516158d9816017850160208801614837565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351615916816028840160208801614837565b01602801949350505050565b60006001600160a01b03808816835280871660208401525060a0604083015261594e60a0830186614ddd565b82810360608401526159608186614ddd565b90508281036080840152615974818561485b565b98975050505050505050565b60006020828403121561599257600080fd5b8151610ceb816146bc565b600060033d1115613b1e5760046000803e5060005160e01c90565b600060443d10156159c65790565b6040516003193d81016004833e81513d67ffffffffffffffff81602484011181841117156159f657505050505090565b8285019150815181811115615a0e5750505050505090565b843d8701016020828501011115615a285750505050505090565b615a3760208286010187614705565b509095945050505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a0608083015261552f60a083018461485b565b600081615a8957615a8961531d565b50600019019056fe71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834fa2646970667358221220ecfc74ac5e949f533a2fd859f6e2d57530955f2021a19661d0a5d5affe67bfbb64736f6c63430008180033000000000000000000000000a87dbcfa18adb7c00593e2c2469d83213c87aecd000000000000000000000000ae975071be8f8ee67addbc1a82488f1c24858067000000000000000000000000f0511f123164602042ab2bcf02111fa5d3fe97cdd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a8000000000000000000000000000000000000000000000000000000000000042b0000000000000000000000000000000000000000000000000000000000000100000000000000000000000000754a3c4b373bcf24895997c59d866ff0b7ae6113000000000000000000000000000000000000000000000000000000000000028a000000000000000000000000000000000000000000000000000000000000004768747470733a2f2f616c6c6f667468657468696e67732e73332e616d617a6f6e6177732e636f6d2f76616c657269612f6c6274772f6d657461646174612f7b69647d2e6a736f6e00000000000000000000000000000000000000000000000000
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106103ea5760003560e01c80636c3b86991161021a578063c50b0d6311610135578063e5558d5e116100c8578063f2fde38b11610097578063f7c519a61161007c578063f7c519a614610a33578063f877a8af14610a46578063fd762d9214610a5957600080fd5b8063f2fde38b14610a0d578063f3154fa114610a2057600080fd5b8063e5558d5e14610998578063e985e9c5146109ab578063efd11b1e146109e7578063f242432a146109fa57600080fd5b8063d547741f11610104578063d547741f1461094c578063d6e7c1d91461095f578063da74222814610972578063db28d3a81461098557600080fd5b8063c50b0d63146108f7578063d007af5c1461091e578063d07f824714610926578063d25815351461093957600080fd5b806395d89b41116101ad578063a9fc664e1161017c578063a9fc664e14610896578063b187bd26146108a9578063be537f43146108bd578063bf7d8146146108d257600080fd5b806395d89b411461082f5780639d645a4414610868578063a217fddf1461087b578063a22cb4651461088357600080fd5b80638749e26f116101e95780638749e26f146107985780638d85c96f146107d45780638da5cb5b146107e757806391d14854146107f857600080fd5b80636c3b86991461076a578063715018a614610772578063797669c91461077a5780638307b56e1461078f57600080fd5b80632e8da8291161030a5780634e1273f41161029d5780635d4c1d461161026c5780635d4c1d46146106fd578063613471621461071d57806361728f3914610730578063696a50b41461075757600080fd5b80634e1273f414610688578063572b6c05146106a857806357455bcb146106ca5780635944c753146106ea57600080fd5b80634082de67116102d95780634082de671461063a57806341f7a0b81461064d578063495c8bf9146106605780634a1e31e81461067557600080fd5b80632e8da829146105ee5780632eb2c2d6146106015780632f2ff15d1461061457806336568abe1461062757600080fd5b806309c1ba2e116103825780631c33b328116103515780631c33b328146105715780631fe543e314610586578063248a9ca3146105995780632a55205a146105bc57600080fd5b806309c1ba2e146104f85780630e89341c1461053857806316c38b3c1461054b5780631b25b0771461055e57600080fd5b806304634d8d116103be57806304634d8d1461047e578063060383411461049157806306fdde03146104a5578063098144d4146104e757600080fd5b8062fdd58e146103ef578063014635461461041557806301ffc9a71461044657806302fe530514610469575b600080fd5b6104026103fd366004614690565b610a6c565b6040519081526020015b60405180910390f35b61042e71721c310194ccfc01e523fc93c9cccfa2a0ac81565b6040516001600160a01b03909116815260200161040c565b6104596104543660046146d2565b610b1a565b604051901515815260200161040c565b61047c610477366004614790565b610b25565b005b61047c61048c366004614802565b610b4a565b60095461045990600160a81b900460ff1681565b60408051808201909152601c81527f56616c657269613a204c616e64204265666f726520546865205761720000000060208201525b60405161040c9190614887565b6004546001600160a01b031661042e565b61051f7f000000000000000000000000000000000000000000000000000000000000042b81565b60405167ffffffffffffffff909116815260200161040c565b6104da61054636600461489a565b610b71565b61047c6105593660046148c1565b610c05565b61045961056c3660046148de565b610c57565b610579600181565b60405161040c919061494b565b61047c6105943660046149f3565b610cf2565b6104026105a736600461489a565b60009081526020819052604090206001015490565b6105cf6105ca366004614a3a565b610d8f565b604080516001600160a01b03909316835260208301919091520161040c565b6104596105fc366004614a5c565b610e4c565b61047c61060f366004614a99565b610f59565b61047c610622366004614b47565b61100d565b61047c610635366004614b47565b611032565b61047c610648366004614a3a565b6110ca565b61047c61065b366004614bbc565b611512565b610668611681565b60405161040c9190614c7a565b61047c610683366004614cc7565b611793565b61069b610696366004614d1a565b6117ef565b60405161040c9190614e19565b6104596106b6366004614a5c565b6006546001600160a01b0391821691161490565b6106dd6106d8366004614e2c565b611925565b60405161040c9190614e61565b61047c6106f8366004614ec5565b611a17565b610705600181565b6040516001600160781b03909116815260200161040c565b61047c61072b366004614f25565b611a40565b6104027fd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a881565b61047c610765366004614f65565b611bd5565b61047c611c1a565b61047c611d0c565b610402600080516020615a9283398151915281565b610402600b5481565b6107bf6107a636600461489a565b600e602052600090815260409020805460019091015482565b6040805192835260208301919091520161040c565b61047c6107e2366004614f9a565b611d20565b6005546001600160a01b031661042e565b610459610806366004614b47565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60408051808201909152600681527f56414c425457000000000000000000000000000000000000000000000000000060208201526104da565b610459610876366004614a5c565b611dce565b610402600081565b61047c61089136600461501d565b611e97565b61047c6108a4366004614a5c565b611ea9565b60095461045990600160a01b900460ff1681565b6108c5611fe3565b60405161040c919061504b565b600c546108e29063ffffffff1681565b60405163ffffffff909116815260200161040c565b6104027ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce86081565b61066861209f565b61047c610934366004615087565b612159565b61047c610947366004614f65565b61218e565b61047c61095a366004614b47565b6121c3565b61047c61096d3660046150ad565b6121e8565b61047c610980366004614a5c565b61235f565b61047c610993366004614a5c565b612389565b61047c6109a63660046150e8565b6123c4565b6104596109b936600461518d565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b61047c6109f536600461489a565b612455565b61047c610a083660046151bb565b612473565b61047c610a1b366004614a5c565b612520565b61047c610a2e366004615224565b6125b0565b61047c610a41366004614f9a565b6125d4565b61047c610a543660046148c1565b61266c565b61047c610a67366004615287565b6126be565b60006001600160a01b038316610aef5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201527f616c6964206f776e65720000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526001602090815260408083206001600160a01b03861684529091529020545b92915050565b6000610b14826127d2565b600080516020615a92833981519152610b3d81612810565b610b4682612821565b5050565b600080516020615a92833981519152610b6281612810565b610b6c838361282d565b505050565b606060038054610b80906152e3565b80601f0160208091040260200160405190810160405280929190818152602001828054610bac906152e3565b8015610bf95780601f10610bce57610100808354040283529160200191610bf9565b820191906000526020600020905b815481529060010190602001808311610bdc57829003601f168201915b50505050509050919050565b600080516020615a92833981519152610c1d81612810565b5060098054911515600160a01b027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6004546000906001600160a01b031615610ce7576004805460405163050bf71960e31b81526001600160a01b03878116938201939093528583166024820152848316604482015291169063285fb8c89060640160006040518083038186803b158015610cc257600080fd5b505afa925050508015610cd3575060015b610cdf57506000610ceb565b506001610ceb565b5060015b9392505050565b336001600160a01b037f000000000000000000000000ae975071be8f8ee67addbc1a82488f1c248580671614610d85576040517f1cf993f40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f000000000000000000000000ae975071be8f8ee67addbc1a82488f1c24858067166024820152604401610ae6565b610b468282612887565b60008281526008602090815260408083208151808301909252546001600160a01b038116808352600160a01b9091046bffffffffffffffffffffffff16928201929092528291610e0e5750604080518082019091526007546001600160a01b0381168252600160a01b90046bffffffffffffffffffffffff1660208201525b602081015160009061271090610e32906bffffffffffffffffffffffff1687615333565b610e3c9190615360565b91519350909150505b9250929050565b6004546000906001600160a01b031615610f515760048054604051635caaa2a960e11b815230928101929092526001600160a01b03169063d72dde5e90829063b955455290602401606060405180830381865afa158015610eb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed59190615374565b602001516040516001600160e01b031960e084901b1681526001600160781b0390911660048201526001600160a01b03851660248201526044015b602060405180830381865afa158015610f2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1491906153e6565b506000919050565b610f616128ab565b6001600160a01b0316856001600160a01b03161480610f875750610f87856109b96128ab565b610ff95760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f7665640000000000000000000000000000000000006064820152608401610ae6565b61100685858585856128b5565b5050505050565b60008281526020819052604090206001015461102881612810565b610b6c8383612b2e565b61103a6128ab565b6001600160a01b0316816001600160a01b0316146110c05760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610ae6565b610b468282612bcd565b600954600160a01b900460ff161561110e576040517f1309a56300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b5481111561114a576040517f69a1c3a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000828152600e6020526040902080548314611192576040517f3a02e7f000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061119c6128ab565b6009546040517fd25815350000000000000000000000000000000000000000000000000000000081526001600160a01b038084166004830152602482018890526044820187905292935091169063d258153590606401600060405180830381600087803b15801561120c57600080fd5b505af1158015611220573d6000803e3d6000fd5b505060095460009250600160a81b900460ff1615905061137a576001600160a01b037f000000000000000000000000ae975071be8f8ee67addbc1a82488f1c2485806716635d3b1d307fd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a87f000000000000000000000000000000000000000000000000000000000000042b600c5460405160e085901b6001600160e01b0319168152600481019390935267ffffffffffffffff90911660248301526003604483015263ffffffff1660648201526001608482015260a4016020604051808303816000875af1158015611316573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061133a9190615403565b905061134881868685612c6a565b604051859082907fbd6dfba7e9a62090fe5538754d1d033d2710db089fe446d1555e343bcd35717490600090a3611006565b600a805490600061138a8361541c565b9190505550611006600a54600e60008881526020019081526020016000206040518060a001604052908160008201548152602001600182015481526020016002820180548060200260200160405190810160405280929190818152602001828054801561141657602002820191906000526020600020905b815481526020019060010190808311611402575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561146e57602002820191906000526020600020905b81548152602001906001019080831161145a575b50505050508152602001600482018054806020026020016040519081016040528092919081815260200182805480156114c657602002820191906000526020600020905b8154815260200190600101908083116114b2575b50505050508152505061150b600a5460408051426020808301919091524482840152606080830194909452825180830390940184526080909101909152815191012090565b8786612cc6565b600080516020615a9283398151915261152a81612810565b868514801561153857508483145b6115845760405162461bcd60e51b815260206004820152600660248201527f2176616c696400000000000000000000000000000000000000000000000000006044820152606401610ae6565b60005b878110156116765761166e8989838181106115a4576115a4615435565b90506020020160208101906115b99190614a5c565b8888848181106115cb576115cb615435565b90506020028101906115dd919061544b565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a925089915086905081811061162357611623615435565b9050602002810190611635919061544b565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612e1b915050565b600101611587565b505050505050505050565b6004546060906001600160a01b0316156117805760048054604051635caaa2a960e11b815230928101929092526001600160a01b031690633fe5df9990829063b955455290602401606060405180830381865afa1580156116e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170a9190615374565b602001516040516001600160e01b031960e084901b1681526001600160781b0390911660048201526024015b600060405180830381865afa158015611753573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261177b9190810190615495565b905090565b5060408051600081526020810190915290565b60005b81811015611006576117e76117a96128ab565b8484848181106117bb576117bb615435565b90506020020160208101906117d09190614a5c565b878760405180602001604052806000815250612473565b600101611796565b606081518351146118685760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d6174636800000000000000000000000000000000000000000000006064820152608401610ae6565b6000835167ffffffffffffffff811115611884576118846146ef565b6040519080825280602002602001820160405280156118ad578160200160208202803683370190505b50905060005b845181101561191d576118f88582815181106118d1576118d1615435565b60200260200101518583815181106118eb576118eb615435565b6020026020010151610a6c565b82828151811061190a5761190a615435565b60209081029190910101526001016118b3565b509392505050565b60606000825167ffffffffffffffff811115611943576119436146ef565b60405190808252806020026020018201604052801561197657816020015b60608152602001906001900390816119615790505b50905060008060005b8551811015611a0d5785818151811061199a5761199a615435565b60200260200101519150600e6000838152602001908152602001600020925082600001548360010154846002016040516020016119d99392919061553a565b6040516020818303038152906040528482815181106119fa576119fa615435565b602090810291909101015260010161197f565b5091949350505050565b600080516020615a92833981519152611a2f81612810565b611a3a848484613000565b50505050565b611a4861305f565b6000611a5c6004546001600160a01b031690565b90506001600160a01b038116611a9e576040517f39ffc7ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051630368065360e61b81526001600160a01b0382169063da0194c090611acc9030908890600401615596565b600060405180830381600087803b158015611ae657600080fd5b505af1158015611afa573d6000803e3d6000fd5b5050604051631182550160e11b81523060048201526001600160781b03861660248201526001600160a01b0384169250632304aa029150604401600060405180830381600087803b158015611b4e57600080fd5b505af1158015611b62573d6000803e3d6000fd5b505060405163235d10c560e21b81523060048201526001600160781b03851660248201526001600160a01b0384169250638d74431491506044015b600060405180830381600087803b158015611bb757600080fd5b505af1158015611bcb573d6000803e3d6000fd5b5050505050505050565b7ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce860611bff81612810565b611a3a84848460405180602001604052806000815250613076565b611c2261305f565b611c3d71721c310194ccfc01e523fc93c9cccfa2a0ac611ea9565b604051630368065360e61b815271721c310194ccfc01e523fc93c9cccfa2a0ac9063da0194c090611c75903090600190600401615596565b600060405180830381600087803b158015611c8f57600080fd5b505af1158015611ca3573d6000803e3d6000fd5b5050604051631182550160e11b81523060048201526001602482015271721c310194ccfc01e523fc93c9cccfa2a0ac9250632304aa029150604401600060405180830381600087803b158015611cf857600080fd5b505af1158015611a3a573d6000803e3d6000fd5b611d146131ac565b611d1e6000613225565b565b7ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce860611d4a81612810565b611dc68686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808a02828101820190935289825290935089925088918291850190849080828437600092018290525060408051602081019091529081529250612e1b915050565b505050505050565b6004546000906001600160a01b031615610f515760048054604051635caaa2a960e11b815230928101929092526001600160a01b031690639445f53090829063b955455290602401606060405180830381865afa158015611e33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e579190615374565b60409081015190516001600160e01b031960e084901b1681526001600160781b0390911660048201526001600160a01b0385166024820152604401610f10565b610b46611ea26128ab565b8383613277565b611eb161305f565b60006001600160a01b0382163b15611f2c576040516301ffc9a760e01b8152600060048201526001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015611f24575060408051601f3d908101601f19168201909252611f21918101906153e6565b60015b15611f2c5790505b6001600160a01b03821615801590611f42575080155b15611f79576040517f32483afb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600454604080516001600160a01b03928316815291841660208301527fcc5dc080ff977b3c3a211fa63ab74f90f658f5ba9d3236e92c8f59570f442aac910160405180910390a150600480546001600160a01b0319166001600160a01b0392909216919091179055565b60408051606081018252600080825260208201819052918101919091526004546001600160a01b03161561207e5760048054604051635caaa2a960e11b815230928101929092526001600160a01b03169063b955455290602401606060405180830381865afa15801561205a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061177b9190615374565b50604080516060810182526000808252602082018190529181019190915290565b6004546060906001600160a01b0316156117805760048054604051635caaa2a960e11b815230928101929092526001600160a01b0316906317e94a6c90829063b955455290602401606060405180830381865afa158015612104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121289190615374565b60409081015190516001600160e01b031960e084901b1681526001600160781b039091166004820152602401611736565b600080516020615a9283398151915261217181612810565b50600c805463ffffffff191663ffffffff92909216919091179055565b7ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce8606121b881612810565b611a3a848484613363565b6000828152602081905260409020600101546121de81612810565b610b6c8383612bcd565b600080516020615a9283398151915261220081612810565b600082602001351161227a5760405162461bcd60e51b815260206004820152602660248201527f4d696e74207175616e746974792073686f756c6420626520677265617465722060448201527f7468616e203000000000000000000000000000000000000000000000000000006064820152608401610ae6565b6000612289604084018461544b565b9050116122d85760405162461bcd60e51b815260206004820152601960248201527f4d7573742068617665206174206c656173742031206974656d000000000000006044820152606401610ae6565b6122e5608083018361544b565b90506122f4606084018461544b565b9050146123435760405162461bcd60e51b815260206004820152600e60248201527f496e76616c696420636f6e6669670000000000000000000000000000000000006044820152606401610ae6565b81356000908152600e602052604090208290611a3a8282615648565b6123676131ac565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b600080516020615a928339815191526123a181612810565b50600980546001600160a01b0319166001600160a01b0392909216919091179055565b600080516020615a928339815191526123dc81612810565b61244c8787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250612e1b915050565b50505050505050565b600080516020615a9283398151915261246d81612810565b50600b55565b61247b6128ab565b6001600160a01b0316856001600160a01b031614806124a157506124a1856109b96128ab565b6125135760405162461bcd60e51b815260206004820152602e60248201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60448201527f6572206f7220617070726f7665640000000000000000000000000000000000006064820152608401610ae6565b611006858585858561350c565b6125286131ac565b6001600160a01b0381166125a45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610ae6565b6125ad81613225565b50565b600080516020615a928339815191526125c881612810565b61100685858585613076565b7ffc774c32e29e21e9ba21cd756bf11bad138fd7eb34eb4d84154c03fe1e0ce8606125fe81612810565b611dc68686868080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808a028281018201909352898252909350899250889182918501908490808284376000920191909152506136d792505050565b600080516020615a9283398151915261268481612810565b5060098054911515600160a81b027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff909216919091179055565b6126c661305f565b6126cf84611ea9565b604051630368065360e61b81526001600160a01b0385169063da0194c0906126fd9030908790600401615596565b600060405180830381600087803b15801561271757600080fd5b505af115801561272b573d6000803e3d6000fd5b5050604051631182550160e11b81523060048201526001600160781b03851660248201526001600160a01b0387169250632304aa029150604401600060405180830381600087803b15801561277f57600080fd5b505af1158015612793573d6000803e3d6000fd5b505060405163235d10c560e21b81523060048201526001600160781b03841660248201526001600160a01b0387169250638d7443149150604401611b9d565b60006001600160e01b031982167f2a55205a000000000000000000000000000000000000000000000000000000001480610b145750610b1482613935565b6125ad8161281c6128ab565b613973565b6003610b46828261575d565b61283782826139e6565b6040516bffffffffffffffffffffffff821681526001600160a01b038316907f8a8bae378cb731c5c40b632330c6836c2f916f48edb967699c86736f9a6a76ef9060200160405180910390a25050565b610b46828260008151811061289e5761289e615435565b6020026020010151613aed565b600061177b613af7565b81518351146129175760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610ae6565b6001600160a01b03841661297b5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610ae6565b60006129856128ab565b9050612995818787878787613b21565b60005b8451811015612aba5760008582815181106129b5576129b5615435565b6020026020010151905060008583815181106129d3576129d3615435565b60209081029190910181015160008481526001835260408082206001600160a01b038e168352909352919091205490915081811015612a675760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608401610ae6565b60008381526001602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290612aa690849061581d565b909155505060019093019250612998915050565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612b0a929190615830565b60405180910390a4612b20818787878787613b5a565b611dc6818787878787613b93565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610b46576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055612b896128ab565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610b46576000828152602081815260408083206001600160a01b03851684529091529020805460ff19169055612c266128ab565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b611a3a84848484604080516060810182526001600160a01b03928316815260208082019586528183019485526000968752600d905294209351845491166001600160a01b03199091161783559051600183015551600290910155565b6000828560200151612cd89190615333565b905060008167ffffffffffffffff811115612cf557612cf56146ef565b604051908082528060200260200182016040528015612d1e578160200160208202803683370190505b50905060008060005b84811015612db957640100000000612d4082600161581d565b612d4b90600a615333565b612d55908a615360565b612d5f919061585e565b9250612d74838a606001518b60800151613d38565b915088604001518281518110612d8c57612d8c615435565b6020026020010151848281518110612da657612da6615435565b6020908102919091010152600101612d27565b612dc38685613da4565b856001600160a01b03168a7fb8886e73a6f3f585c87b51e4888e9cdcc0e915f6f4f0a1e410c722ce0398240b8a8c600001518989604051612e079493929190615872565b60405180910390a350505050505050505050565b6001600160a01b038416612e7b5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610ae6565b8151835114612edd5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610ae6565b6000612ee76128ab565b9050612ef881600087878787613b21565b60005b8451811015612f8957838181518110612f1657612f16615435565b602002602001015160016000878481518110612f3457612f34615435565b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000206000828254612f7c919061581d565b9091555050600101612efb565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051612fda929190615830565b60405180910390a4612ff181600087878787613b5a565b61100681600087878787613b93565b61300b838383613eba565b6040516bffffffffffffffffffffffff821681526001600160a01b0383169084907f7f5b076c952c0ec86e5425963c1326dd0f03a3595c19f81d765e8ff559a6e33c906020015b60405180910390a3505050565b611d1e600080516020615a92833981519152612810565b6001600160a01b0384166130d65760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610ae6565b60006130e06128ab565b905060006130ed85613fd2565b905060006130fa85613fd2565b905061310b83600089858589613b21565b60008681526001602090815260408083206001600160a01b038b1684529091528120805487929061313d90849061581d565b909155505060408051878152602081018790526001600160a01b03808a1692600092918716917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461319d83600089858589613b5a565b61244c8360008989898961401d565b6131b46128ab565b6001600160a01b03166131cf6005546001600160a01b031690565b6001600160a01b031614611d1e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ae6565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b0316036132fe5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c6600000000000000000000000000000000000000000000006064820152608401610ae6565b6001600160a01b03838116600081815260026020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319101613052565b6001600160a01b0383166133c55760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608401610ae6565b60006133cf6128ab565b905060006133dc84613fd2565b905060006133e984613fd2565b905061340983876000858560405180602001604052806000815250613b21565b60008581526001602090815260408083206001600160a01b038a168452909152902054848110156134885760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608401610ae6565b60008681526001602090815260408083206001600160a01b038b81168086529184528285208a8703905582518b81529384018a90529092908816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461244c84886000868660405180602001604052806000815250613b5a565b6001600160a01b0384166135705760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610ae6565b600061357a6128ab565b9050600061358785613fd2565b9050600061359485613fd2565b90506135a4838989858589613b21565b60008681526001602090815260408083206001600160a01b038c1684529091529020548581101561362a5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b6064820152608401610ae6565b60008781526001602090815260408083206001600160a01b038d8116855292528083208985039055908a1682528120805488929061366990849061581d565b909155505060408051888152602081018890526001600160a01b03808b16928c821692918816917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46136c9848a8a86868a613b5a565b611676848a8a8a8a8a61401d565b6001600160a01b0383166137395760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b6064820152608401610ae6565b805182511461379b5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b6064820152608401610ae6565b60006137a56128ab565b90506137c581856000868660405180602001604052806000815250613b21565b60005b83518110156138be5760008482815181106137e5576137e5615435565b60200260200101519050600084838151811061380357613803615435565b60209081029190910181015160008481526001835260408082206001600160a01b038c1683529093529190912054909150818110156138905760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b6064820152608401610ae6565b60009283526001602081815260408086206001600160a01b038c1687529091529093209190039055016137c8565b5060006001600160a01b0316846001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb868660405161390f929190615830565b60405180910390a4611a3a81856000868660405180602001604052806000815250613b5a565b60006001600160e01b031982167f86455d28000000000000000000000000000000000000000000000000000000001480610b145750610b1482614119565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610b46576139a48161418b565b6139af83602061419d565b6040516020016139c09291906158a1565b60408051601f198184030181529082905262461bcd60e51b8252610ae691600401614887565b6127106bffffffffffffffffffffffff82161115613a595760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610ae6565b6001600160a01b038216613aaf5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c6964207265636569766572000000000000006044820152606401610ae6565b604080518082019091526001600160a01b039092168083526bffffffffffffffffffffffff9091166020909201829052600160a01b90910217600755565b610b46828261437e565b6006546000906001600160a01b03163303613b19575060131936013560601c90565b503390565b90565b825160005b81811015611bcb57613b528787878481518110613b4557613b45615435565b60200260200101516144d9565b600101613b26565b825160005b81811015611bcb57613b8b8787878481518110613b7e57613b7e615435565b602002602001015161454c565b600101613b5f565b6001600160a01b0384163b15611dc65760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190613bd79089908990889088908890600401615922565b6020604051808303816000875af1925050508015613c12575060408051601f3d908101601f19168201909252613c0f91810190615980565b60015b613cc757613c1e61599d565b806308c379a003613c575750613c326159b8565b80613c3d5750613c59565b8060405162461bcd60e51b8152600401610ae69190614887565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560448201527f526563656976657220696d706c656d656e7465720000000000000000000000006064820152608401610ae6565b6001600160e01b0319811663bc197c8160e01b1461244c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b6064820152608401610ae6565b815160009061ffff8516908290613d4f908361585e565b9050848181518110613d6357613d63615435565b6020026020010151600883901c1015613d7f579150610ceb9050565b838181518110613d9157613d91615435565b6020026020010151925050509392505050565b805160008167ffffffffffffffff811115613dc157613dc16146ef565b604051908082528060200260200182016040528015613dea578160200160208202803683370190505b50905060008267ffffffffffffffff811115613e0857613e086146ef565b604051908082528060200260200182016040528015613e31578160200160208202803683370190505b50905060005b83811015613e9e57848181518110613e5157613e51615435565b6020026020010151838281518110613e6b57613e6b615435565b6020026020010181815250506001828281518110613e8b57613e8b615435565b6020908102919091010152600101613e37565b5061100685838360405180602001604052806000815250612e1b565b6127106bffffffffffffffffffffffff82161115613f2d5760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b6064820152608401610ae6565b6001600160a01b038216613f835760405162461bcd60e51b815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610ae6565b6040805180820182526001600160a01b0393841681526bffffffffffffffffffffffff92831660208083019182526000968752600890529190942093519051909116600160a01b029116179055565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061400c5761400c615435565b602090810291909101015292915050565b6001600160a01b0384163b15611dc65760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906140619089908990889088908890600401615a42565b6020604051808303816000875af192505050801561409c575060408051601f3d908101601f1916820190925261409991810190615980565b60015b6140a857613c1e61599d565b6001600160e01b0319811663f23a6e6160e01b1461244c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b6064820152608401610ae6565b60006001600160e01b031982167fd9b67a2600000000000000000000000000000000000000000000000000000000148061417c57506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b80610b145750610b14826145b1565b6060610b146001600160a01b03831660145b606060006141ac836002615333565b6141b790600261581d565b67ffffffffffffffff8111156141cf576141cf6146ef565b6040519080825280601f01601f1916602001820160405280156141f9576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061423057614230615435565b60200101906001600160f81b031916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061427b5761427b615435565b60200101906001600160f81b031916908160001a905350600061429f846002615333565b6142aa90600161581d565b90505b600181111561432f577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106142eb576142eb615435565b1a60f81b82828151811061430157614301615435565b60200101906001600160f81b031916908160001a90535060049490941c9361432881615a7a565b90506142ad565b508315610ceb5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610ae6565b6000828152600d602090815260408083206001808201548552600e845293829020825160a08101845281548152948101548585015260028101805484518187028101870186528181529396610b6c968a9691959186019391929083018282801561440757602002820191906000526020600020905b8154815260200190600101908083116143f3575b505050505081526020016003820180548060200260200160405190810160405280929190818152602001828054801561445f57602002820191906000526020600020905b81548152602001906001019080831161444b575b50505050508152602001600482018054806020026020016040519081016040528092919081815260200182805480156144b757602002820191906000526020600020905b8154815260200190600101908083116144a3575b50505091909252505050600284015484548691906001600160a01b0316612cc6565b6001600160a01b0383811615908316158180156144f35750805b1561451157604051635cbd944160e01b815260040160405180910390fd5b8115614527576145226125ad6128ab565b611006565b8015614538576145226125ad6128ab565b6110066145436128ab565b868686346145ff565b6001600160a01b0383811615908316158180156145665750805b1561458457604051635cbd944160e01b815260040160405180910390fd5b8115614595576145226125ad6128ab565b80156145a6576145226125ad6128ab565b6110066125ad6128ab565b60006001600160e01b031982167f7965db0b000000000000000000000000000000000000000000000000000000001480610b1457506301ffc9a760e01b6001600160e01b0319831614610b14565b6004546001600160a01b031615611006576004805460405163050bf71960e31b81526001600160a01b03888116938201939093528683166024820152858316604482015291169063285fb8c89060640160006040518083038186803b15801561466757600080fd5b505afa158015611676573d6000803e3d6000fd5b6001600160a01b03811681146125ad57600080fd5b600080604083850312156146a357600080fd5b82356146ae8161467b565b946020939093013593505050565b6001600160e01b0319811681146125ad57600080fd5b6000602082840312156146e457600080fd5b8135610ceb816146bc565b634e487b7160e01b600052604160045260246000fd5b601f8201601f1916810167ffffffffffffffff8111828210171561472b5761472b6146ef565b6040525050565b600067ffffffffffffffff83111561474c5761474c6146ef565b604051614763601f8501601f191660200182614705565b80915083815284848401111561477857600080fd5b83836020830137600060208583010152509392505050565b6000602082840312156147a257600080fd5b813567ffffffffffffffff8111156147b957600080fd5b8201601f810184136147ca57600080fd5b6147d984823560208401614732565b949350505050565b80356bffffffffffffffffffffffff811681146147fd57600080fd5b919050565b6000806040838503121561481557600080fd5b82356148208161467b565b915061482e602084016147e1565b90509250929050565b60005b8381101561485257818101518382015260200161483a565b50506000910152565b60008151808452614873816020860160208601614837565b601f01601f19169290920160200192915050565b602081526000610ceb602083018461485b565b6000602082840312156148ac57600080fd5b5035919050565b80151581146125ad57600080fd5b6000602082840312156148d357600080fd5b8135610ceb816148b3565b6000806000606084860312156148f357600080fd5b83356148fe8161467b565b9250602084013561490e8161467b565b9150604084013561491e8161467b565b809150509250925092565b6007811061494757634e487b7160e01b600052602160045260246000fd5b9052565b60208101610b148284614929565b600067ffffffffffffffff821115614973576149736146ef565b5060051b60200190565b600082601f83011261498e57600080fd5b8135602061499b82614959565b6040516149a88282614705565b80915083815260208101915060208460051b8701019350868411156149cc57600080fd5b602086015b848110156149e857803583529183019183016149d1565b509695505050505050565b60008060408385031215614a0657600080fd5b82359150602083013567ffffffffffffffff811115614a2457600080fd5b614a308582860161497d565b9150509250929050565b60008060408385031215614a4d57600080fd5b50508035926020909101359150565b600060208284031215614a6e57600080fd5b8135610ceb8161467b565b600082601f830112614a8a57600080fd5b610ceb83833560208501614732565b600080600080600060a08688031215614ab157600080fd5b8535614abc8161467b565b94506020860135614acc8161467b565b9350604086013567ffffffffffffffff80821115614ae957600080fd5b614af589838a0161497d565b94506060880135915080821115614b0b57600080fd5b614b1789838a0161497d565b93506080880135915080821115614b2d57600080fd5b50614b3a88828901614a79565b9150509295509295909350565b60008060408385031215614b5a57600080fd5b823591506020830135614b6c8161467b565b809150509250929050565b60008083601f840112614b8957600080fd5b50813567ffffffffffffffff811115614ba157600080fd5b6020830191508360208260051b8501011115610e4557600080fd5b60008060008060008060006080888a031215614bd757600080fd5b873567ffffffffffffffff80821115614bef57600080fd5b614bfb8b838c01614b77565b909950975060208a0135915080821115614c1457600080fd5b614c208b838c01614b77565b909750955060408a0135915080821115614c3957600080fd5b614c458b838c01614b77565b909550935060608a0135915080821115614c5e57600080fd5b50614c6b8a828b01614a79565b91505092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015614cbb5783516001600160a01b031683529284019291840191600101614c96565b50909695505050505050565b60008060008060608587031215614cdd57600080fd5b8435935060208501359250604085013567ffffffffffffffff811115614d0257600080fd5b614d0e87828801614b77565b95989497509550505050565b60008060408385031215614d2d57600080fd5b823567ffffffffffffffff80821115614d4557600080fd5b818501915085601f830112614d5957600080fd5b81356020614d6682614959565b604051614d738282614705565b83815260059390931b8501820192828101915089841115614d9357600080fd5b948201945b83861015614dba578535614dab8161467b565b82529482019490820190614d98565b96505086013592505080821115614dd057600080fd5b50614a308582860161497d565b60008151808452602080850194506020840160005b83811015614e0e57815187529582019590820190600101614df2565b509495945050505050565b602081526000610ceb6020830184614ddd565b600060208284031215614e3e57600080fd5b813567ffffffffffffffff811115614e5557600080fd5b6147d98482850161497d565b600060208083016020845280855180835260408601915060408160051b87010192506020870160005b82811015614eb857603f19888603018452614ea685835161485b565b94509285019290850190600101614e8a565b5092979650505050505050565b600080600060608486031215614eda57600080fd5b833592506020840135614eec8161467b565b9150614efa604085016147e1565b90509250925092565b600781106125ad57600080fd5b6001600160781b03811681146125ad57600080fd5b600080600060608486031215614f3a57600080fd5b8335614f4581614f03565b92506020840135614f5581614f10565b9150604084013561491e81614f10565b600080600060608486031215614f7a57600080fd5b8335614f858161467b565b95602085013595506040909401359392505050565b600080600080600060608688031215614fb257600080fd5b8535614fbd8161467b565b9450602086013567ffffffffffffffff80821115614fda57600080fd5b614fe689838a01614b77565b90965094506040880135915080821115614fff57600080fd5b5061500c88828901614b77565b969995985093965092949392505050565b6000806040838503121561503057600080fd5b823561503b8161467b565b91506020830135614b6c816148b3565b600060608201905061505e828451614929565b60208301516001600160781b038082166020850152806040860151166040850152505092915050565b60006020828403121561509957600080fd5b813563ffffffff81168114610ceb57600080fd5b6000602082840312156150bf57600080fd5b813567ffffffffffffffff8111156150d657600080fd5b820160a08185031215610ceb57600080fd5b6000806000806000806080878903121561510157600080fd5b863561510c8161467b565b9550602087013567ffffffffffffffff8082111561512957600080fd5b6151358a838b01614b77565b9097509550604089013591508082111561514e57600080fd5b61515a8a838b01614b77565b9095509350606089013591508082111561517357600080fd5b5061518089828a01614a79565b9150509295509295509295565b600080604083850312156151a057600080fd5b82356151ab8161467b565b91506020830135614b6c8161467b565b600080600080600060a086880312156151d357600080fd5b85356151de8161467b565b945060208601356151ee8161467b565b93506040860135925060608601359150608086013567ffffffffffffffff81111561521857600080fd5b614b3a88828901614a79565b6000806000806080858703121561523a57600080fd5b84356152458161467b565b93506020850135925060408501359150606085013567ffffffffffffffff81111561526f57600080fd5b61527b87828801614a79565b91505092959194509250565b6000806000806080858703121561529d57600080fd5b84356152a88161467b565b935060208501356152b881614f03565b925060408501356152c881614f10565b915060608501356152d881614f10565b939692955090935050565b600181811c908216806152f757607f821691505b60208210810361531757634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610b1457610b1461531d565b634e487b7160e01b600052601260045260246000fd5b60008261536f5761536f61534a565b500490565b60006060828403121561538657600080fd5b6040516060810181811067ffffffffffffffff821117156153a9576153a96146ef565b60405282516153b781614f03565b815260208301516153c781614f10565b602082015260408301516153da81614f10565b60408201529392505050565b6000602082840312156153f857600080fd5b8151610ceb816148b3565b60006020828403121561541557600080fd5b5051919050565b60006001820161542e5761542e61531d565b5060010190565b634e487b7160e01b600052603260045260246000fd5b6000808335601e1984360301811261546257600080fd5b83018035915067ffffffffffffffff82111561547d57600080fd5b6020019150600581901b3603821315610e4557600080fd5b600060208083850312156154a857600080fd5b825167ffffffffffffffff8111156154bf57600080fd5b8301601f810185136154d057600080fd5b80516154db81614959565b6040516154e88282614705565b82815260059290921b830184019184810191508783111561550857600080fd5b928401925b8284101561552f5783516155208161467b565b8252928401929084019061550d565b979650505050505050565b600060608201858352602085602085015260606040850152818554808452608086019150866000526020600020935060005b818110156155885784548352600194850194928401920161556c565b509098975050505050505050565b6001600160a01b038316815260408101610ceb6020830184614929565b5b81811015610b4657600081556001016155b4565b67ffffffffffffffff8311156155e0576155e06146ef565b680100000000000000008311156155f9576155f96146ef565b80548382558084101561561f5781600052602060002061561d8282018683016155b3565b505b50818160005260208060002060005b8681101561244c578335828201559282019260010161562e565b81358155600160208084013560018401556002830161566a604086018661544b565b67ffffffffffffffff811115615682576156826146ef565b6801000000000000000081111561569b5761569b6146ef565b8254818455808210156156c1578360005260206000206156bf8282018483016155b3565b505b50600092835260208320925b818110156156e6578235848201559184019185016156cd565b5050505050506156f9606083018361544b565b6157078183600386016155c8565b5050615716608083018361544b565b611a3a8183600486016155c8565b601f821115610b6c57806000526020600020601f840160051c8101602085101561574b5750805b611006601f850160051c8301826155b3565b815167ffffffffffffffff811115615777576157776146ef565b61578b8161578584546152e3565b84615724565b602080601f8311600181146157c057600084156157a85750858301515b600019600386901b1c1916600185901b178555611dc6565b600085815260208120601f198616915b828110156157ef578886015182559484019460019091019084016157d0565b508582101561580d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80820180821115610b1457610b1461531d565b6040815260006158436040830185614ddd565b82810360208401526158558185614ddd565b95945050505050565b60008261586d5761586d61534a565b500690565b8481528360208201528260408201526080606082015260006158976080830184614ddd565b9695505050505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516158d9816017850160208801614837565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351615916816028840160208801614837565b01602801949350505050565b60006001600160a01b03808816835280871660208401525060a0604083015261594e60a0830186614ddd565b82810360608401526159608186614ddd565b90508281036080840152615974818561485b565b98975050505050505050565b60006020828403121561599257600080fd5b8151610ceb816146bc565b600060033d1115613b1e5760046000803e5060005160e01c90565b600060443d10156159c65790565b6040516003193d81016004833e81513d67ffffffffffffffff81602484011181841117156159f657505050505090565b8285019150815181811115615a0e5750505050505090565b843d8701016020828501011115615a285750505050505090565b615a3760208286010187614705565b509095945050505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a0608083015261552f60a083018461485b565b600081615a8957615a8961531d565b50600019019056fe71f3d55856e4058ed06ee057d79ada615f65cdf5f9ee88181b914225088f834fa2646970667358221220ecfc74ac5e949f533a2fd859f6e2d57530955f2021a19661d0a5d5affe67bfbb64736f6c63430008180033