Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Poap
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
No with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.28; import {FreezableUpgradeable} from "../utils/FreezableUpgradeable.sol"; import {AccessControlDefaultAdminRulesUpgradeable} from "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlDefaultAdminRulesUpgradeable.sol"; import {ERC721PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721PausableUpgradeable.sol"; import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import {IERC4906} from "@openzeppelin/contracts/interfaces/IERC4906.sol"; import {IERC721} from "@openzeppelin/contracts/interfaces/IERC721.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; /** * @title Poap * @dev This contract allows the minting, burning, pausing, and freezing of POAP tokens. * Each token is associated with a specific event ID. * It is designed for deployment on any chain, except Gnosis and Ethereum, * where a POAP contract already exists. * * @author * - Agustin Lavarello * @custom:reviewers * - Rodrigo Manuel Navarro Lajous * - Juan Manuel Martinez */ contract Poap is ERC721PausableUpgradeable, AccessControlDefaultAdminRulesUpgradeable, FreezableUpgradeable, IERC4906 { using Strings for uint256; mapping(uint256 tokenId => uint256 eventId) private _tokenEvent; /// @dev Thrown when the arguments of batch tokens don't have the same length. error BatchMintTokenInvalidArgumentLength(); /// @dev Error for insufficient permissions to freeze a token. error InsufficientPermissions(address caller, uint256 tokenId); /** * @dev Emitted when a new POAP Token is minted. * @param eventId ID of the minted poap. * @param poapId ID of the minted poap. * @param owner Address of the new token owner. */ event Mint( uint256 indexed eventId, uint256 indexed poapId, address indexed owner ); /** * @dev Emitted when token is created. * Maintained for indexing retro-compatibility */ event EventToken(uint256 indexed eventId, uint256 tokenId); // Role definitions for access control // This role is the admin role for all the other ones bytes32 public constant ROLE_MANAGER_ROLE = keccak256("ROLE_MANAGER_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE"); bytes32 public constant FREEZER_ROLE = keccak256("FREEZER_ROLE"); bytes32 public constant METADATA_MANAGER_ROLE = keccak256("METADATA_MANAGER_ROLE"); // Variables to manage poaps IDs and metadata base URIs string private _baseMetadataURI; string private _baseMetadataURISuffix; uint256 private _totalSupply; /** * @dev Initializes the contract, setting up initial roles with the admin role * and starting the supply in 0 * @param admin Address to be granted the admin role and the role manager role. * @param initialAdminDelay Time in seconds that we need to wait to change the admin role * @param freezeDuration The duration in seconds that the tokens will be frozen */ function initialize( address admin, uint48 initialAdminDelay, uint256 freezeDuration ) public initializer { __ERC721_init("POAP", "The Proof of Attendance Protocol"); __AccessControlDefaultAdminRules_init(initialAdminDelay, admin); __Freezable_init(freezeDuration); bytes32[5] memory roles = [ MINTER_ROLE, BURNER_ROLE, PAUSER_ROLE, FREEZER_ROLE, METADATA_MANAGER_ROLE ]; for (uint256 i = 0; i < roles.length; i++) { _setRoleAdmin(roles[i], ROLE_MANAGER_ROLE); } _totalSupply = 0; } /** * @dev Mint specific token to address. * Requires * - The msg sender to be the admin, or event minter for the specific event Id * - The contract does not have to be paused * @param eventId ( uint256 ) EventId for the new token * @param tokenId ( uint256 ) Token Id for the new token * @param owner ( address ) The address that will receive the minted tokens. */ function mintToken(uint256 eventId, uint256 tokenId, address owner) public { _mintToken(eventId, tokenId, owner); _totalSupply += 1; } /** * @dev Mint multiple tokens in a single transaction. * Requirements: * - The caller must have the MINTER_ROLE. * - The contract must not be paused. * - The lengths of `eventIds`, `tokenIds`, and `owners` must be the same. * @param eventIds An array of event IDs associated with the tokens. * @param tokenIds An array of token IDs to mint. * @param owners An array of addresses that will receive the minted tokens. */ function batchMintTokens( uint256[] calldata eventIds, uint256[] calldata tokenIds, address[] calldata owners ) public { uint256 amountToMint = tokenIds.length; if (eventIds.length != amountToMint || owners.length != amountToMint) { revert BatchMintTokenInvalidArgumentLength(); } for (uint256 i = 0; i < amountToMint; i++) { _mintToken(eventIds[i], tokenIds[i], owners[i]); } _totalSupply += amountToMint; } /** * @dev Transfers the ownership of a given token ID to another address (Implements ERC71) * Wrapper for function extended from ERC721 ( https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol ) * Requires * - The msg sender to be the owner, approved, or operator * - The contract does not have to be paused * - The token to be transferred must not be frozen. * @param from ( address ) The address of the current owner of the token * @param to ( address ) The address to receive the ownership of the given token ID * @param tokenId ( uint256 ) ID of the token to be transferred */ function transferFrom( address from, address to, uint256 tokenId ) public override(ERC721Upgradeable, IERC721) whenNotFrozen(tokenId) { super.transferFrom(from, to, tokenId); } /** * @dev Safely transfers the ownership of a given token ID to another address (Implements ERC71) * Wrapper for function extended from ERC721 ( https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol ) * Requires * - The msg sender to be the owner, approved, or operator * - The contract does not have to be paused * - The token to be transferred must not be frozen. * @param from ( address ) The address of the current owner of the token * @param to ( address ) The address to receive the ownership of the given token ID * @param tokenId ( uint256 ) ID of the token to be transferred * @param _data ( bytes ) Data to send along with a safe transfer check */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public override(ERC721Upgradeable, IERC721) whenNotFrozen(tokenId) { super.safeTransferFrom(from, to, tokenId, _data); } /** * @dev Burns a specific token. * Only the owner of the token or the address with role BURNER_ROLE can burn it * @param tokenId ID of the token to burn. * Requires: * - The contract does not have to be paused */ function burn(uint256 tokenId) public virtual { if (hasRole(BURNER_ROLE, _msgSender())) { // Maintain consistent error handling as when the token owner initiates a burn. if (_ownerOf(tokenId) == address(0)) { revert ERC721NonexistentToken(tokenId); } _update(address(0), tokenId, address(0)); } else { _update(address(0), tokenId, _msgSender()); } } /** * @dev Gets the Event Id for the token * @param tokenId ( uint256 ) The Token Id you want to query * @return uint256 representing the Event id for the token */ function tokenEvent(uint256 tokenId) public view returns (uint256) { return _tokenEvent[tokenId]; } /** * @dev Pauses all token transfers, mints and burns. */ function pause() public onlyRole(PAUSER_ROLE) { _pause(); } /** * @dev Unpauses all token transfers, mints and burns. */ function unpause() public onlyRole(PAUSER_ROLE) { _unpause(); } /** * @dev Freezes a specific ERC721 token. * Requirements: * - Caller must have the FREEZER role, token owner or approved operator. * - Contract must not be paused. * - Token must not be frozen. * * @param tokenId The ID of the ERC721 token to freeze. */ function freeze( uint256 tokenId ) public whenNotPaused whenNotFrozen(tokenId) { if ( !_isAuthorized(ownerOf(tokenId), _msgSender(), tokenId) && !hasRole(FREEZER_ROLE, _msgSender()) ) { revert InsufficientPermissions(_msgSender(), tokenId); } _freeze(tokenId); } /** * @dev Unfreezes a specific ERC721 token. * Requirements: * - Caller must be an admin. * - Contract must not be paused. * - Token must be currently frozen. * * @param tokenId The ID of the ERC721 token to unfreeze. */ function unfreeze( uint256 tokenId ) public onlyRole(FREEZER_ROLE) whenNotPaused whenFrozen(tokenId) { _unfreeze(tokenId); } /** * @dev Sets a new base URI for metadata. * @param newBaseMetadataURI New base URI to set. */ function setBaseMetadataURI( string calldata newBaseMetadataURI ) public onlyRole(METADATA_MANAGER_ROLE) { _baseMetadataURI = newBaseMetadataURI; } /** * @dev Sets a new suffix for metadata URIs. * @param newBaseMetadataURISuffix New suffix to set. */ function setBaseMetadataURISuffix( string calldata newBaseMetadataURISuffix ) public onlyRole(METADATA_MANAGER_ROLE) { _baseMetadataURISuffix = newBaseMetadataURISuffix; } /** * @dev Sets a new freeze duration * @param newDuration New freeze duration */ function setFreezeDuration( uint256 newDuration ) public onlyRole(FREEZER_ROLE) { _setFreezeDuration(newDuration); } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI( uint256 tokenId ) public view override(ERC721Upgradeable) returns (string memory) { _requireOwned(tokenId); return string( abi.encodePacked( _baseURI(), this.tokenEvent(tokenId).toString(), "/", tokenId.toString(), _baseMetadataURISuffix ) ); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override( ERC721Upgradeable, AccessControlDefaultAdminRulesUpgradeable, IERC165 ) returns (bool) { return super.supportsInterface(interfaceId); } /// @dev Returns the base metadata URI. function baseMetadataURI() public view virtual returns (string memory) { return _baseMetadataURI; } /// @dev Returns the base metadata URI suffix. function baseMetadataURISuffix() public view virtual returns (string memory) { return _baseMetadataURISuffix; } /// @dev Returns the total number of minted tokens. function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev Emits an event to notify that metadata has been updated for a token. * @param tokenId ID of the token whose metadata was updated. */ function emitMetadataUpdate( uint256 tokenId ) public onlyRole(METADATA_MANAGER_ROLE) { emit MetadataUpdate(tokenId); } /** * @dev Emits an event to notify that metadata has been updated for a range of tokens. * @param fromTokenId ID of the first token in the range. * @param toTokenId ID of the last token in the range. */ function emitBatchMetadataUpdate( uint256 fromTokenId, uint256 toTokenId ) public onlyRole(METADATA_MANAGER_ROLE) { emit BatchMetadataUpdate(fromTokenId, toTokenId); } /// @dev Returns the base URI for metadata. function _baseURI() internal view virtual override returns (string memory) { return _baseMetadataURI; } /** * @dev Internal function to handle the minting of a specific token. * Note: This function does not increase the total supply. * Requirements: * - The caller must have the MINTER_ROLE. * - The contract must not be paused. * @param eventId The event ID associated with the new token. * @param tokenId The ID of the token to mint. * @param owner The address that will receive the minted token. */ function _mintToken( uint256 eventId, uint256 tokenId, address owner ) private onlyRole(MINTER_ROLE) { _safeMint(owner, tokenId); _tokenEvent[tokenId] = eventId; emit Mint(eventId, tokenId, owner); emit EventToken(eventId, tokenId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) pragma solidity ^0.8.20; import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol"; import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol"; import {ERC165Upgradeable} from "../utils/introspection/ERC165Upgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * 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}: * * ```solidity * 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. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable { struct RoleData { mapping(address account => bool) hasRole; bytes32 adminRole; } bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /// @custom:storage-location erc7201:openzeppelin.storage.AccessControl struct AccessControlStorage { mapping(bytes32 role => RoleData) _roles; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControl")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800; function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) { assembly { $.slot := AccessControlStorageLocation } } /** * @dev Modifier that checks that an account has a specific role. Reverts * with an {AccessControlUnauthorizedAccount} error including the required role. */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } function __AccessControl_init() internal onlyInitializing { } function __AccessControl_init_unchained() internal onlyInitializing { } /** * @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 returns (bool) { AccessControlStorage storage $ = _getAccessControlStorage(); return $._roles[role].hasRole[account]; } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` * is missing `role`. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert AccessControlUnauthorizedAccount(account, role); } } /** * @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 returns (bytes32) { AccessControlStorage storage $ = _getAccessControlStorage(); 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 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 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 `callerConfirmation`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address callerConfirmation) public virtual { if (callerConfirmation != _msgSender()) { revert AccessControlBadConfirmation(); } _revokeRole(role, callerConfirmation); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { AccessControlStorage storage $ = _getAccessControlStorage(); bytes32 previousAdminRole = getRoleAdmin(role); $._roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual returns (bool) { AccessControlStorage storage $ = _getAccessControlStorage(); if (!hasRole(role, account)) { $._roles[role].hasRole[account] = true; emit RoleGranted(role, account, _msgSender()); return true; } else { return false; } } /** * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { AccessControlStorage storage $ = _getAccessControlStorage(); if (hasRole(role, account)) { $._roles[role].hasRole[account] = false; emit RoleRevoked(role, account, _msgSender()); return true; } else { return false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/AccessControlDefaultAdminRules.sol) pragma solidity ^0.8.20; import {IAccessControlDefaultAdminRules} from "@openzeppelin/contracts/access/extensions/IAccessControlDefaultAdminRules.sol"; import {AccessControlUpgradeable} from "../AccessControlUpgradeable.sol"; import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {IERC5313} from "@openzeppelin/contracts/interfaces/IERC5313.sol"; import {Initializable} from "../../proxy/utils/Initializable.sol"; /** * @dev Extension of {AccessControl} that allows specifying special rules to manage * the `DEFAULT_ADMIN_ROLE` holder, which is a sensitive role with special permissions * over other roles that may potentially have privileged rights in the system. * * If a specific role doesn't have an admin role assigned, the holder of the * `DEFAULT_ADMIN_ROLE` will have the ability to grant it and revoke it. * * This contract implements the following risk mitigations on top of {AccessControl}: * * * Only one account holds the `DEFAULT_ADMIN_ROLE` since deployment until it's potentially renounced. * * Enforces a 2-step process to transfer the `DEFAULT_ADMIN_ROLE` to another account. * * Enforces a configurable delay between the two steps, with the ability to cancel before the transfer is accepted. * * The delay can be changed by scheduling, see {changeDefaultAdminDelay}. * * It is not possible to use another role to manage the `DEFAULT_ADMIN_ROLE`. * * Example usage: * * ```solidity * contract MyToken is AccessControlDefaultAdminRules { * constructor() AccessControlDefaultAdminRules( * 3 days, * msg.sender // Explicit initial `DEFAULT_ADMIN_ROLE` holder * ) {} * } * ``` */ abstract contract AccessControlDefaultAdminRulesUpgradeable is Initializable, IAccessControlDefaultAdminRules, IERC5313, AccessControlUpgradeable { /// @custom:storage-location erc7201:openzeppelin.storage.AccessControlDefaultAdminRules struct AccessControlDefaultAdminRulesStorage { // pending admin pair read/written together frequently address _pendingDefaultAdmin; uint48 _pendingDefaultAdminSchedule; // 0 == unset uint48 _currentDelay; address _currentDefaultAdmin; // pending delay pair read/written together frequently uint48 _pendingDelay; uint48 _pendingDelaySchedule; // 0 == unset } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControlDefaultAdminRules")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant AccessControlDefaultAdminRulesStorageLocation = 0xeef3dac4538c82c8ace4063ab0acd2d15cdb5883aa1dff7c2673abb3d8698400; function _getAccessControlDefaultAdminRulesStorage() private pure returns (AccessControlDefaultAdminRulesStorage storage $) { assembly { $.slot := AccessControlDefaultAdminRulesStorageLocation } } /** * @dev Sets the initial values for {defaultAdminDelay} and {defaultAdmin} address. */ function __AccessControlDefaultAdminRules_init(uint48 initialDelay, address initialDefaultAdmin) internal onlyInitializing { __AccessControlDefaultAdminRules_init_unchained(initialDelay, initialDefaultAdmin); } function __AccessControlDefaultAdminRules_init_unchained(uint48 initialDelay, address initialDefaultAdmin) internal onlyInitializing { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); if (initialDefaultAdmin == address(0)) { revert AccessControlInvalidDefaultAdmin(address(0)); } $._currentDelay = initialDelay; _grantRole(DEFAULT_ADMIN_ROLE, initialDefaultAdmin); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlDefaultAdminRules).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC5313-owner}. */ function owner() public view virtual returns (address) { return defaultAdmin(); } /// /// Override AccessControl role management /// /** * @dev See {AccessControl-grantRole}. Reverts for `DEFAULT_ADMIN_ROLE`. */ function grantRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl) { if (role == DEFAULT_ADMIN_ROLE) { revert AccessControlEnforcedDefaultAdminRules(); } super.grantRole(role, account); } /** * @dev See {AccessControl-revokeRole}. Reverts for `DEFAULT_ADMIN_ROLE`. */ function revokeRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl) { if (role == DEFAULT_ADMIN_ROLE) { revert AccessControlEnforcedDefaultAdminRules(); } super.revokeRole(role, account); } /** * @dev See {AccessControl-renounceRole}. * * For the `DEFAULT_ADMIN_ROLE`, it only allows renouncing in two steps by first calling * {beginDefaultAdminTransfer} to the `address(0)`, so it's required that the {pendingDefaultAdmin} schedule * has also passed when calling this function. * * After its execution, it will not be possible to call `onlyRole(DEFAULT_ADMIN_ROLE)` functions. * * NOTE: Renouncing `DEFAULT_ADMIN_ROLE` will leave the contract without a {defaultAdmin}, * thereby disabling any functionality that is only available for it, and the possibility of reassigning a * non-administrated role. */ function renounceRole(bytes32 role, address account) public virtual override(AccessControlUpgradeable, IAccessControl) { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) { (address newDefaultAdmin, uint48 schedule) = pendingDefaultAdmin(); if (newDefaultAdmin != address(0) || !_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) { revert AccessControlEnforcedDefaultAdminDelay(schedule); } delete $._pendingDefaultAdminSchedule; } super.renounceRole(role, account); } /** * @dev See {AccessControl-_grantRole}. * * For `DEFAULT_ADMIN_ROLE`, it only allows granting if there isn't already a {defaultAdmin} or if the * role has been previously renounced. * * NOTE: Exposing this function through another mechanism may make the `DEFAULT_ADMIN_ROLE` * assignable again. Make sure to guarantee this is the expected behavior in your implementation. */ function _grantRole(bytes32 role, address account) internal virtual override returns (bool) { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); if (role == DEFAULT_ADMIN_ROLE) { if (defaultAdmin() != address(0)) { revert AccessControlEnforcedDefaultAdminRules(); } $._currentDefaultAdmin = account; } return super._grantRole(role, account); } /** * @dev See {AccessControl-_revokeRole}. */ function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); if (role == DEFAULT_ADMIN_ROLE && account == defaultAdmin()) { delete $._currentDefaultAdmin; } return super._revokeRole(role, account); } /** * @dev See {AccessControl-_setRoleAdmin}. Reverts for `DEFAULT_ADMIN_ROLE`. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual override { if (role == DEFAULT_ADMIN_ROLE) { revert AccessControlEnforcedDefaultAdminRules(); } super._setRoleAdmin(role, adminRole); } /// /// AccessControlDefaultAdminRules accessors /// /** * @inheritdoc IAccessControlDefaultAdminRules */ function defaultAdmin() public view virtual returns (address) { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); return $._currentDefaultAdmin; } /** * @inheritdoc IAccessControlDefaultAdminRules */ function pendingDefaultAdmin() public view virtual returns (address newAdmin, uint48 schedule) { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); return ($._pendingDefaultAdmin, $._pendingDefaultAdminSchedule); } /** * @inheritdoc IAccessControlDefaultAdminRules */ function defaultAdminDelay() public view virtual returns (uint48) { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); uint48 schedule = $._pendingDelaySchedule; return (_isScheduleSet(schedule) && _hasSchedulePassed(schedule)) ? $._pendingDelay : $._currentDelay; } /** * @inheritdoc IAccessControlDefaultAdminRules */ function pendingDefaultAdminDelay() public view virtual returns (uint48 newDelay, uint48 schedule) { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); schedule = $._pendingDelaySchedule; return (_isScheduleSet(schedule) && !_hasSchedulePassed(schedule)) ? ($._pendingDelay, schedule) : (0, 0); } /** * @inheritdoc IAccessControlDefaultAdminRules */ function defaultAdminDelayIncreaseWait() public view virtual returns (uint48) { return 5 days; } /// /// AccessControlDefaultAdminRules public and internal setters for defaultAdmin/pendingDefaultAdmin /// /** * @inheritdoc IAccessControlDefaultAdminRules */ function beginDefaultAdminTransfer(address newAdmin) public virtual onlyRole(DEFAULT_ADMIN_ROLE) { _beginDefaultAdminTransfer(newAdmin); } /** * @dev See {beginDefaultAdminTransfer}. * * Internal function without access restriction. */ function _beginDefaultAdminTransfer(address newAdmin) internal virtual { uint48 newSchedule = SafeCast.toUint48(block.timestamp) + defaultAdminDelay(); _setPendingDefaultAdmin(newAdmin, newSchedule); emit DefaultAdminTransferScheduled(newAdmin, newSchedule); } /** * @inheritdoc IAccessControlDefaultAdminRules */ function cancelDefaultAdminTransfer() public virtual onlyRole(DEFAULT_ADMIN_ROLE) { _cancelDefaultAdminTransfer(); } /** * @dev See {cancelDefaultAdminTransfer}. * * Internal function without access restriction. */ function _cancelDefaultAdminTransfer() internal virtual { _setPendingDefaultAdmin(address(0), 0); } /** * @inheritdoc IAccessControlDefaultAdminRules */ function acceptDefaultAdminTransfer() public virtual { (address newDefaultAdmin, ) = pendingDefaultAdmin(); if (_msgSender() != newDefaultAdmin) { // Enforce newDefaultAdmin explicit acceptance. revert AccessControlInvalidDefaultAdmin(_msgSender()); } _acceptDefaultAdminTransfer(); } /** * @dev See {acceptDefaultAdminTransfer}. * * Internal function without access restriction. */ function _acceptDefaultAdminTransfer() internal virtual { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); (address newAdmin, uint48 schedule) = pendingDefaultAdmin(); if (!_isScheduleSet(schedule) || !_hasSchedulePassed(schedule)) { revert AccessControlEnforcedDefaultAdminDelay(schedule); } _revokeRole(DEFAULT_ADMIN_ROLE, defaultAdmin()); _grantRole(DEFAULT_ADMIN_ROLE, newAdmin); delete $._pendingDefaultAdmin; delete $._pendingDefaultAdminSchedule; } /// /// AccessControlDefaultAdminRules public and internal setters for defaultAdminDelay/pendingDefaultAdminDelay /// /** * @inheritdoc IAccessControlDefaultAdminRules */ function changeDefaultAdminDelay(uint48 newDelay) public virtual onlyRole(DEFAULT_ADMIN_ROLE) { _changeDefaultAdminDelay(newDelay); } /** * @dev See {changeDefaultAdminDelay}. * * Internal function without access restriction. */ function _changeDefaultAdminDelay(uint48 newDelay) internal virtual { uint48 newSchedule = SafeCast.toUint48(block.timestamp) + _delayChangeWait(newDelay); _setPendingDelay(newDelay, newSchedule); emit DefaultAdminDelayChangeScheduled(newDelay, newSchedule); } /** * @inheritdoc IAccessControlDefaultAdminRules */ function rollbackDefaultAdminDelay() public virtual onlyRole(DEFAULT_ADMIN_ROLE) { _rollbackDefaultAdminDelay(); } /** * @dev See {rollbackDefaultAdminDelay}. * * Internal function without access restriction. */ function _rollbackDefaultAdminDelay() internal virtual { _setPendingDelay(0, 0); } /** * @dev Returns the amount of seconds to wait after the `newDelay` will * become the new {defaultAdminDelay}. * * The value returned guarantees that if the delay is reduced, it will go into effect * after a wait that honors the previously set delay. * * See {defaultAdminDelayIncreaseWait}. */ function _delayChangeWait(uint48 newDelay) internal view virtual returns (uint48) { uint48 currentDelay = defaultAdminDelay(); // When increasing the delay, we schedule the delay change to occur after a period of "new delay" has passed, up // to a maximum given by defaultAdminDelayIncreaseWait, by default 5 days. For example, if increasing from 1 day // to 3 days, the new delay will come into effect after 3 days. If increasing from 1 day to 10 days, the new // delay will come into effect after 5 days. The 5 day wait period is intended to be able to fix an error like // using milliseconds instead of seconds. // // When decreasing the delay, we wait the difference between "current delay" and "new delay". This guarantees // that an admin transfer cannot be made faster than "current delay" at the time the delay change is scheduled. // For example, if decreasing from 10 days to 3 days, the new delay will come into effect after 7 days. return newDelay > currentDelay ? uint48(Math.min(newDelay, defaultAdminDelayIncreaseWait())) // no need to safecast, both inputs are uint48 : currentDelay - newDelay; } /// /// Private setters /// /** * @dev Setter of the tuple for pending admin and its schedule. * * May emit a DefaultAdminTransferCanceled event. */ function _setPendingDefaultAdmin(address newAdmin, uint48 newSchedule) private { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); (, uint48 oldSchedule) = pendingDefaultAdmin(); $._pendingDefaultAdmin = newAdmin; $._pendingDefaultAdminSchedule = newSchedule; // An `oldSchedule` from `pendingDefaultAdmin()` is only set if it hasn't been accepted. if (_isScheduleSet(oldSchedule)) { // Emit for implicit cancellations when another default admin was scheduled. emit DefaultAdminTransferCanceled(); } } /** * @dev Setter of the tuple for pending delay and its schedule. * * May emit a DefaultAdminDelayChangeCanceled event. */ function _setPendingDelay(uint48 newDelay, uint48 newSchedule) private { AccessControlDefaultAdminRulesStorage storage $ = _getAccessControlDefaultAdminRulesStorage(); uint48 oldSchedule = $._pendingDelaySchedule; if (_isScheduleSet(oldSchedule)) { if (_hasSchedulePassed(oldSchedule)) { // Materialize a virtual delay $._currentDelay = $._pendingDelay; } else { // Emit for implicit cancellations when another delay was scheduled. emit DefaultAdminDelayChangeCanceled(); } } $._pendingDelay = newDelay; $._pendingDelaySchedule = newSchedule; } /// /// Private helpers /// /** * @dev Defines if an `schedule` is considered set. For consistency purposes. */ function _isScheduleSet(uint48 schedule) private pure returns (bool) { return schedule != 0; } /** * @dev Defines if an `schedule` is considered passed. For consistency purposes. */ function _hasSchedulePassed(uint48 schedule) private view returns (bool) { return schedule < block.timestamp; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.20; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; import {ContextUpgradeable} from "../../utils/ContextUpgradeable.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import {ERC165Upgradeable} from "../../utils/introspection/ERC165Upgradeable.sol"; import {IERC721Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; import {Initializable} from "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ abstract contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721, IERC721Metadata, IERC721Errors { using Strings for uint256; /// @custom:storage-location erc7201:openzeppelin.storage.ERC721 struct ERC721Storage { // Token name string _name; // Token symbol string _symbol; mapping(uint256 tokenId => address) _owners; mapping(address owner => uint256) _balances; mapping(uint256 tokenId => address) _tokenApprovals; mapping(address owner => mapping(address operator => bool)) _operatorApprovals; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC721")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant ERC721StorageLocation = 0x80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300; function _getERC721Storage() private pure returns (ERC721Storage storage $) { assembly { $.slot := ERC721StorageLocation } } /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC721_init_unchained(name_, symbol_); } function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { ERC721Storage storage $ = _getERC721Storage(); $._name = name_; $._symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual returns (uint256) { ERC721Storage storage $ = _getERC721Storage(); if (owner == address(0)) { revert ERC721InvalidOwner(address(0)); } return $._balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual returns (address) { return _requireOwned(tokenId); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual returns (string memory) { ERC721Storage storage $ = _getERC721Storage(); return $._name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual returns (string memory) { ERC721Storage storage $ = _getERC721Storage(); return $._symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual returns (string memory) { _requireOwned(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual { _approve(to, tokenId, _msgSender()); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual returns (address) { _requireOwned(tokenId); return _getApproved(tokenId); } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual returns (bool) { ERC721Storage storage $ = _getERC721Storage(); return $._operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here. address previousOwner = _update(to, tokenId, _msgSender()); if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual { transferFrom(from, to, tokenId); _checkOnERC721Received(from, to, tokenId, data); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist * * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`. */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); return $._owners[tokenId]; } /** * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted. */ function _getApproved(uint256 tokenId) internal view virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); return $._tokenApprovals[tokenId]; } /** * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in * particular (ignoring whether it is owned by `owner`). * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) { return spender != address(0) && (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender); } /** * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner. * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets * the `spender` for the specific `tokenId`. * * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this * assumption. */ function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual { if (!_isAuthorized(owner, spender, tokenId)) { if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } else { revert ERC721InsufficientApproval(spender, tokenId); } } } /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that * a uint256 would ever overflow from increments when these increments are bounded to uint128 values. * * WARNING: Increasing an account's balance using this function tends to be paired with an override of the * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership * remain consistent with one another. */ function _increaseBalance(address account, uint128 value) internal virtual { ERC721Storage storage $ = _getERC721Storage(); unchecked { $._balances[account] += value; } } /** * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update. * * The `auth` argument is optional. If the value passed is non 0, then this function will check that * `auth` is either the owner of the token, or approved to operate on the token (by the owner). * * Emits a {Transfer} event. * * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}. */ function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) { ERC721Storage storage $ = _getERC721Storage(); address from = _ownerOf(tokenId); // Perform (optional) operator check if (auth != address(0)) { _checkAuthorized(from, auth, tokenId); } // Execute the update if (from != address(0)) { // Clear approval. No need to re-authorize or emit the Approval event _approve(address(0), tokenId, address(0), false); unchecked { $._balances[from] -= 1; } } if (to != address(0)) { unchecked { $._balances[to] += 1; } } $._owners[tokenId] = to; emit Transfer(from, to, tokenId); return from; } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner != address(0)) { revert ERC721InvalidSender(address(0)); } } /** * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); _checkOnERC721Received(address(0), to, tokenId, data); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal { address previousOwner = _update(address(0), tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal { if (to == address(0)) { revert ERC721InvalidReceiver(address(0)); } address previousOwner = _update(to, tokenId, address(0)); if (previousOwner == address(0)) { revert ERC721NonexistentToken(tokenId); } else if (previousOwner != from) { revert ERC721IncorrectOwner(from, tokenId, previousOwner); } } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients * are aware of the ERC721 standard to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is like {safeTransferFrom} in the sense that it invokes * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `tokenId` token must exist and be owned by `from`. * - `to` cannot be the zero address. * - `from` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId) internal { _safeTransfer(from, to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); _checkOnERC721Received(from, to, tokenId, data); } /** * @dev Approve `to` to operate on `tokenId` * * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is * either the owner of the token, or approved to operate on all tokens held by this owner. * * Emits an {Approval} event. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address to, uint256 tokenId, address auth) internal { _approve(to, tokenId, auth, true); } /** * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not * emitted in the context of transfers. */ function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual { ERC721Storage storage $ = _getERC721Storage(); // Avoid reading the owner unless necessary if (emitEvent || auth != address(0)) { address owner = _requireOwned(tokenId); // We do not use _isAuthorized because single-token approvals should not be able to call approve if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) { revert ERC721InvalidApprover(auth); } if (emitEvent) { emit Approval(owner, to, tokenId); } } $._tokenApprovals[tokenId] = to; } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Requirements: * - operator can't be the address zero. * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { ERC721Storage storage $ = _getERC721Storage(); if (operator == address(0)) { revert ERC721InvalidOperator(operator); } $._operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned). * Returns the owner. * * Overrides to ownership logic should be done to {_ownerOf}. */ function _requireOwned(uint256 tokenId) internal view returns (address) { address owner = _ownerOf(tokenId); if (owner == address(0)) { revert ERC721NonexistentToken(tokenId); } return owner; } /** * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private { if (to.code.length > 0) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { if (retval != IERC721Receiver.onERC721Received.selector) { revert ERC721InvalidReceiver(to); } } catch (bytes memory reason) { if (reason.length == 0) { revert ERC721InvalidReceiver(to); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Pausable.sol) pragma solidity ^0.8.20; import {ERC721Upgradeable} from "../ERC721Upgradeable.sol"; import {PausableUpgradeable} from "../../../utils/PausableUpgradeable.sol"; import {Initializable} from "../../../proxy/utils/Initializable.sol"; /** * @dev ERC721 token with pausable token transfers, minting and burning. * * Useful for scenarios such as preventing trades until the end of an evaluation * period, or having an emergency switch for freezing all token transfers in the * event of a large bug. * * IMPORTANT: This contract does not include public pause and unpause functions. In * addition to inheriting this contract, you must define both functions, invoking the * {Pausable-_pause} and {Pausable-_unpause} internal functions, with appropriate * access control, e.g. using {AccessControl} or {Ownable}. Not doing so will * make the contract pause mechanism of the contract unreachable, and thus unusable. */ abstract contract ERC721PausableUpgradeable is Initializable, ERC721Upgradeable, PausableUpgradeable { function __ERC721Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __ERC721Pausable_init_unchained() internal onlyInitializing { } /** * @dev See {ERC721-_update}. * * Requirements: * * - the contract must not be paused. */ function _update( address to, uint256 tokenId, address auth ) internal virtual override whenNotPaused returns (address) { return super._update(to, tokenId, auth); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import {Initializable} from "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165Upgradeable is Initializable, IERC165 { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol) pragma solidity ^0.8.20; import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /// @custom:storage-location erc7201:openzeppelin.storage.Pausable struct PausableStorage { bool _paused; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Pausable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300; function _getPausableStorage() private pure returns (PausableStorage storage $) { assembly { $.slot := PausableStorageLocation } } /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { PausableStorage storage $ = _getPausableStorage(); $._paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { PausableStorage storage $ = _getPausableStorage(); return $._paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { if (paused()) { revert EnforcedPause(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert ExpectedPause(); } } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { PausableStorage storage $ = _getPausableStorage(); $._paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { PausableStorage storage $ = _getPausableStorage(); $._paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/IAccessControlDefaultAdminRules.sol) pragma solidity ^0.8.20; import {IAccessControl} from "../IAccessControl.sol"; /** * @dev External interface of AccessControlDefaultAdminRules declared to support ERC165 detection. */ interface IAccessControlDefaultAdminRules is IAccessControl { /** * @dev The new default admin is not a valid default admin. */ error AccessControlInvalidDefaultAdmin(address defaultAdmin); /** * @dev At least one of the following rules was violated: * * - The `DEFAULT_ADMIN_ROLE` must only be managed by itself. * - The `DEFAULT_ADMIN_ROLE` must only be held by one account at the time. * - Any `DEFAULT_ADMIN_ROLE` transfer must be in two delayed steps. */ error AccessControlEnforcedDefaultAdminRules(); /** * @dev The delay for transferring the default admin delay is enforced and * the operation must wait until `schedule`. * * NOTE: `schedule` can be 0 indicating there's no transfer scheduled. */ error AccessControlEnforcedDefaultAdminDelay(uint48 schedule); /** * @dev Emitted when a {defaultAdmin} transfer is started, setting `newAdmin` as the next * address to become the {defaultAdmin} by calling {acceptDefaultAdminTransfer} only after `acceptSchedule` * passes. */ event DefaultAdminTransferScheduled(address indexed newAdmin, uint48 acceptSchedule); /** * @dev Emitted when a {pendingDefaultAdmin} is reset if it was never accepted, regardless of its schedule. */ event DefaultAdminTransferCanceled(); /** * @dev Emitted when a {defaultAdminDelay} change is started, setting `newDelay` as the next * delay to be applied between default admin transfer after `effectSchedule` has passed. */ event DefaultAdminDelayChangeScheduled(uint48 newDelay, uint48 effectSchedule); /** * @dev Emitted when a {pendingDefaultAdminDelay} is reset if its schedule didn't pass. */ event DefaultAdminDelayChangeCanceled(); /** * @dev Returns the address of the current `DEFAULT_ADMIN_ROLE` holder. */ function defaultAdmin() external view returns (address); /** * @dev Returns a tuple of a `newAdmin` and an accept schedule. * * After the `schedule` passes, the `newAdmin` will be able to accept the {defaultAdmin} role * by calling {acceptDefaultAdminTransfer}, completing the role transfer. * * A zero value only in `acceptSchedule` indicates no pending admin transfer. * * NOTE: A zero address `newAdmin` means that {defaultAdmin} is being renounced. */ function pendingDefaultAdmin() external view returns (address newAdmin, uint48 acceptSchedule); /** * @dev Returns the delay required to schedule the acceptance of a {defaultAdmin} transfer started. * * This delay will be added to the current timestamp when calling {beginDefaultAdminTransfer} to set * the acceptance schedule. * * NOTE: If a delay change has been scheduled, it will take effect as soon as the schedule passes, making this * function returns the new delay. See {changeDefaultAdminDelay}. */ function defaultAdminDelay() external view returns (uint48); /** * @dev Returns a tuple of `newDelay` and an effect schedule. * * After the `schedule` passes, the `newDelay` will get into effect immediately for every * new {defaultAdmin} transfer started with {beginDefaultAdminTransfer}. * * A zero value only in `effectSchedule` indicates no pending delay change. * * NOTE: A zero value only for `newDelay` means that the next {defaultAdminDelay} * will be zero after the effect schedule. */ function pendingDefaultAdminDelay() external view returns (uint48 newDelay, uint48 effectSchedule); /** * @dev Starts a {defaultAdmin} transfer by setting a {pendingDefaultAdmin} scheduled for acceptance * after the current timestamp plus a {defaultAdminDelay}. * * Requirements: * * - Only can be called by the current {defaultAdmin}. * * Emits a DefaultAdminRoleChangeStarted event. */ function beginDefaultAdminTransfer(address newAdmin) external; /** * @dev Cancels a {defaultAdmin} transfer previously started with {beginDefaultAdminTransfer}. * * A {pendingDefaultAdmin} not yet accepted can also be cancelled with this function. * * Requirements: * * - Only can be called by the current {defaultAdmin}. * * May emit a DefaultAdminTransferCanceled event. */ function cancelDefaultAdminTransfer() external; /** * @dev Completes a {defaultAdmin} transfer previously started with {beginDefaultAdminTransfer}. * * After calling the function: * * - `DEFAULT_ADMIN_ROLE` should be granted to the caller. * - `DEFAULT_ADMIN_ROLE` should be revoked from the previous holder. * - {pendingDefaultAdmin} should be reset to zero values. * * Requirements: * * - Only can be called by the {pendingDefaultAdmin}'s `newAdmin`. * - The {pendingDefaultAdmin}'s `acceptSchedule` should've passed. */ function acceptDefaultAdminTransfer() external; /** * @dev Initiates a {defaultAdminDelay} update by setting a {pendingDefaultAdminDelay} scheduled for getting * into effect after the current timestamp plus a {defaultAdminDelay}. * * This function guarantees that any call to {beginDefaultAdminTransfer} done between the timestamp this * method is called and the {pendingDefaultAdminDelay} effect schedule will use the current {defaultAdminDelay} * set before calling. * * The {pendingDefaultAdminDelay}'s effect schedule is defined in a way that waiting until the schedule and then * calling {beginDefaultAdminTransfer} with the new delay will take at least the same as another {defaultAdmin} * complete transfer (including acceptance). * * The schedule is designed for two scenarios: * * - When the delay is changed for a larger one the schedule is `block.timestamp + newDelay` capped by * {defaultAdminDelayIncreaseWait}. * - When the delay is changed for a shorter one, the schedule is `block.timestamp + (current delay - new delay)`. * * A {pendingDefaultAdminDelay} that never got into effect will be canceled in favor of a new scheduled change. * * Requirements: * * - Only can be called by the current {defaultAdmin}. * * Emits a DefaultAdminDelayChangeScheduled event and may emit a DefaultAdminDelayChangeCanceled event. */ function changeDefaultAdminDelay(uint48 newDelay) external; /** * @dev Cancels a scheduled {defaultAdminDelay} change. * * Requirements: * * - Only can be called by the current {defaultAdmin}. * * May emit a DefaultAdminDelayChangeCanceled event. */ function rollbackDefaultAdminDelay() external; /** * @dev Maximum time in seconds for an increase to {defaultAdminDelay} (that is scheduled using {changeDefaultAdminDelay}) * to take effect. Default to 5 days. * * When the {defaultAdminDelay} is scheduled to be increased, it goes into effect after the new delay has passed with * the purpose of giving enough time for reverting any accidental change (i.e. using milliseconds instead of seconds) * that may lock the contract. However, to avoid excessive schedules, the wait is capped by this function and it can * be overrode for a custom {defaultAdminDelay} increase scheduling. * * IMPORTANT: Make sure to add a reasonable amount of time while overriding this value, otherwise, * there's a risk of setting a high new delay that goes into effect almost immediately without the * possibility of human intervention in the case of an input error (eg. set milliseconds instead of seconds). */ function defaultAdminDelayIncreaseWait() external view returns (uint48); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @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. */ 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 `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; import {IERC721} from "./IERC721.sol"; /// @title EIP-721 Metadata Update Extension interface IERC4906 is IERC165, IERC721 { /// @dev This event emits when the metadata of a token is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFT. event MetadataUpdate(uint256 _tokenId); /// @dev This event emits when the metadata of a range of tokens is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFTs. event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5313.sol) pragma solidity ^0.8.20; /** * @dev Interface for the Light Contract Ownership Standard. * * A standardized minimal interface required to identify an account that controls a contract */ interface IERC5313 { /** * @dev Gets the address of the owner. */ function owner() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC721.sol) pragma solidity ^0.8.20; import {IERC721} from "../token/ERC721/IERC721.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.20; import {IERC721} from "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or * {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (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 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 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. uint256 twos = denominator & (0 - denominator); 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 (unsignedRoundsUp(rounding) && 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 * towards zero. * * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * 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 256, 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; import {Math} from "./math/Math.sol"; import {SignedMath} from "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @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), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @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) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } 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); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.8.28; import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; /** * @title Freezable * @dev A contract that allows objects to be frozen and unfrozen with specific durations. * It provides functions to manage the freezing state of objects. * The contract that implements this will have to represent the id of the object as a uint256. * For example an ERC721 can use the token id as the object id. * * @author * - Agustin Lavarello * @custom:reviewers * - Rodrigo Manuel Navarro Lajous * - Juan Manuel Martinez */ contract FreezableUpgradeable is Initializable, ContextUpgradeable { /// @custom:storage-location poap:poap.storage.freezable struct FreezableStorage { /// @dev Mapping to store the timestamp until which an object is frozen. mapping(uint256 id => uint256 time) _frozenUntil; /// @dev Duration (in seconds) for which objects will be frozen. uint256 freezeDuration; } // keccak256(abi.encode(uint256(keccak256("poap.storage.Freezable")) - 1)) & ~bytes32(uint256(0xff)) // solhint-disable-next-line const-name-snakecase bytes32 private constant FreezableStorageLocation = 0xbd126dd2a6be31261d2bc770804fa46ffa8b92371cd3131388a6665931760900; function _getFreezableStorage() private pure returns (FreezableStorage storage $) { // solhint-disable-next-line no-inline-assembly assembly { $.slot := FreezableStorageLocation } } /// @dev Emitted when an object is frozen. event Freeze(uint256 indexed id); /// @dev Emitted when an object is unfrozen. event Unfreeze(uint256 indexed id); /// @dev Emitted when a an object is unfrozen. event SetFreezeDuration( uint256 indexed previousDuration, uint256 indexed duration, address indexed sender ); /// @dev Thrown when an id is frozen, but an operation requires it to be unfrozen. error IdIsFrozen(uint256 id); /// @dev Thrown when an id is not frozen, but an operation requires it to be frozen. error IdNotFrozen(uint256 id); /// @dev Thrown when an invalid freeze duration is set. error FreezeDurationInvalid(); /** * @dev Modifier to restrict access to functions when the object is not frozen. * Reverts with `ObjectIsFrozen` if the object is frozen. * @param id The ID of the object to check. */ modifier whenNotFrozen(uint256 id) { if (isFrozen(id)) revert IdIsFrozen(id); _; } /** * @dev Modifier to restrict access to functions when the object is frozen. * Reverts with `ObjectNotFrozen` if the object is not frozen. * @param id The ID of the object to check. */ modifier whenFrozen(uint256 id) { if (!isFrozen(id)) revert IdNotFrozen(id); _; } /** * @dev Initializes the contract. Sets the default freeze duration. * @param duration Initial duration for freezing objects (in seconds). */ // solhint-disable-next-line func-name-mixedcase function __Freezable_init(uint256 duration) internal onlyInitializing { __Freezable_init_unchained(duration); } // solhint-disable-next-line func-name-mixedcase function __Freezable_init_unchained( uint256 duration ) internal onlyInitializing { _setFreezeDuration(duration); } /** * @dev Returns the timestamp until which the object is frozen. * @param id The ID of the object. * @return Timestamp until the object is frozen. */ function getFreezeTime(uint256 id) public view returns (uint256) { FreezableStorage storage $ = _getFreezableStorage(); return $._frozenUntil[id]; } /** * @dev Returns the duration for which objects will remain frozen. * @return Duration in seconds. */ function freezeDuration() public view returns (uint256) { FreezableStorage storage $ = _getFreezableStorage(); return $.freezeDuration; } /** * @dev Checks if the object is currently frozen. * @param id The ID of the object. * @return `true` if the object is frozen, otherwise `false`. */ function isFrozen(uint256 id) public view returns (bool) { FreezableStorage storage $ = _getFreezableStorage(); return $._frozenUntil[id] >= block.timestamp; } /** * @dev Sets the duration for which objects will remain frozen. * This will not update the freeze duration of the tokens that are already frozen. * Can only be called internally to ensure controlled logic. * Reverts with `InvalidFreezeDuration` if the provided duration is zero. * @param duration Duration in seconds. */ function _setFreezeDuration(uint256 duration) internal { if (duration == 0) revert FreezeDurationInvalid(); FreezableStorage storage $ = _getFreezableStorage(); uint256 previousDuration = $.freezeDuration; $.freezeDuration = duration; emit SetFreezeDuration(previousDuration, duration, _msgSender()); } /** * @dev Freezes an object for the configured duration. * Can only be called internally by authorized functions. * @param id The ID of the object to freeze. */ function _freeze(uint256 id) internal { FreezableStorage storage $ = _getFreezableStorage(); $._frozenUntil[id] = block.timestamp + $.freezeDuration; emit Freeze(id); } /** * @dev Unfreezes an object, removing it from the frozen state. * Can only be called internally by authorized functions. * @param id The ID of the object to unfreeze. */ function _unfreeze(uint256 id) internal { FreezableStorage storage $ = _getFreezableStorage(); // Gas-efficient deletion of mapping entry. delete $._frozenUntil[id]; emit Unfreeze(id); } }
{ "evmVersion": "paris", "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"uint48","name":"schedule","type":"uint48"}],"name":"AccessControlEnforcedDefaultAdminDelay","type":"error"},{"inputs":[],"name":"AccessControlEnforcedDefaultAdminRules","type":"error"},{"inputs":[{"internalType":"address","name":"defaultAdmin","type":"address"}],"name":"AccessControlInvalidDefaultAdmin","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"BatchMintTokenInvalidArgumentLength","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"FreezeDurationInvalid","type":"error"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"IdIsFrozen","type":"error"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"IdNotFrozen","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"InsufficientPermissions","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"}],"name":"BatchMetadataUpdate","type":"event"},{"anonymous":false,"inputs":[],"name":"DefaultAdminDelayChangeCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint48","name":"newDelay","type":"uint48"},{"indexed":false,"internalType":"uint48","name":"effectSchedule","type":"uint48"}],"name":"DefaultAdminDelayChangeScheduled","type":"event"},{"anonymous":false,"inputs":[],"name":"DefaultAdminTransferCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"},{"indexed":false,"internalType":"uint48","name":"acceptSchedule","type":"uint48"}],"name":"DefaultAdminTransferScheduled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"eventId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"EventToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Freeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"MetadataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"eventId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"poapId","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"previousDuration","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"SetFreezeDuration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Unfreeze","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"BURNER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FREEZER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"METADATA_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLE_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptDefaultAdminTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseMetadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseMetadataURISuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"eventIds","type":"uint256[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address[]","name":"owners","type":"address[]"}],"name":"batchMintTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"beginDefaultAdminTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelDefaultAdminTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"newDelay","type":"uint48"}],"name":"changeDefaultAdminDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultAdminDelay","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultAdminDelayIncreaseWait","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"internalType":"uint256","name":"toTokenId","type":"uint256"}],"name":"emitBatchMetadataUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"emitMetadataUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freezeDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getFreezeTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint48","name":"initialAdminDelay","type":"uint48"},{"internalType":"uint256","name":"freezeDuration","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"isFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"eventId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"mintToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingDefaultAdmin","outputs":[{"internalType":"address","name":"newAdmin","type":"address"},{"internalType":"uint48","name":"schedule","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingDefaultAdminDelay","outputs":[{"internalType":"uint48","name":"newDelay","type":"uint48"},{"internalType":"uint48","name":"schedule","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rollbackDefaultAdminDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseMetadataURI","type":"string"}],"name":"setBaseMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseMetadataURISuffix","type":"string"}],"name":"setBaseMetadataURISuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"setFreezeDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenEvent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"unfreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052348015600f57600080fd5b506154948061001f6000396000f3fe608060405234801561001057600080fd5b50600436106103835760003560e01c80636ca2aa95116101de578063b88d4fde1161010f578063d5391393116100ad578063d890c8e21161007c578063d890c8e2146109ea578063e63ab1e914610a06578063e985e9c514610a24578063f0df844b14610a5457610383565b8063d53913931461098a578063d547741f146109a8578063d602b9fd146109c4578063d7a78db8146109ce57610383565b8063cc5b3105116100e9578063cc5b310514610925578063cc8463c814610943578063cefc142914610961578063cf6eefb71461096b57610383565b8063b88d4fde146108bb578063c6b54b3c146108d7578063c87b56dd146108f557610383565b806391d148541161017c578063a1eda53c11610156578063a1eda53c14610846578063a217fddf14610865578063a22cb46514610883578063a48301141461089f57610383565b806391d14854146107c857806395d89b41146107f8578063a08947991461081657610383565b80638456cb59116101b85780638456cb591461075257806384ef8ffc1461075c5780638da5cb5b1461077a57806390fdd8971461079857610383565b80636ca2aa95146106ea57806370a08231146107065780637e518ec81461073657610383565b80633190b9ea116102b85780635b2bd79e11610256578063634e93da11610230578063634e93da146106665780636352211e14610682578063649a5ec7146106b25780636623fc46146106ce57610383565b80635b2bd79e1461060e5780635c975abb1461062c5780635e813d2d1461064a57610383565b806342842e0e1161029257806342842e0e1461059a57806342966c68146105b6578063440991bd146105d2578063529470e8146105f057610383565b80633190b9ea1461055857806336568abe146105745780633f4ba83a1461059057610383565b8063127a52981161032557806323b872dd116102ff57806323b872dd146104d2578063248a9ca3146104ee578063282c51f31461051e5780632f2ff15d1461053c57610383565b8063127a52981461046857806318160ddd146104985780631cddf50a146104b657610383565b806306fdde031161036157806306fdde03146103f4578063081812fc14610412578063095ea7b3146104425780630aa6220b1461045e57610383565b806301ffc9a714610388578063022d63fb146103b857806306a85f0f146103d6575b600080fd5b6103a2600480360381019061039d9190614175565b610a70565b6040516103af91906141bd565b60405180910390f35b6103c0610a82565b6040516103cd91906141f9565b60405180910390f35b6103de610a8d565b6040516103eb919061422d565b60405180910390f35b6103fc610ab1565b60405161040991906142d8565b60405180910390f35b61042c60048036038101906104279190614330565b610b52565b604051610439919061439e565b60405180910390f35b61045c600480360381019061045791906143e5565b610b6e565b005b610466610b84565b005b610482600480360381019061047d9190614330565b610b9c565b60405161048f9190614434565b60405180910390f35b6104a0610bb8565b6040516104ad9190614434565b60405180910390f35b6104d060048036038101906104cb919061450a565b610bc2565b005b6104ec60048036038101906104e791906145be565b610cb5565b005b6105086004803603810190610503919061463d565b610d12565b604051610515919061422d565b60405180910390f35b610526610d40565b604051610533919061422d565b60405180910390f35b6105566004803603810190610551919061466a565b610d64565b005b610572600480360381019061056d9190614330565b610dae565b005b61058e6004803603810190610589919061466a565b610e13565b005b610598610f37565b005b6105b460048036038101906105af91906145be565b610f6c565b005b6105d060048036038101906105cb9190614330565b610f8c565b005b6105da611066565b6040516105e79190614434565b60405180910390f35b6105f861107e565b604051610605919061422d565b60405180910390f35b6106166110a2565b60405161062391906142d8565b60405180910390f35b610634611134565b60405161064191906141bd565b60405180910390f35b610664600480360381019061065f91906146d6565b611159565b005b610680600480360381019061067b9190614729565b611497565b005b61069c60048036038101906106979190614330565b6114b1565b6040516106a9919061439e565b60405180910390f35b6106cc60048036038101906106c79190614756565b6114c3565b005b6106e860048036038101906106e39190614330565b6114dd565b005b61070460048036038101906106ff9190614330565b611568565b005b610720600480360381019061071b9190614729565b61159f565b60405161072d9190614434565b60405180910390f35b610750600480360381019061074b91906147d9565b611668565b005b61075a6116a9565b005b6107646116de565b604051610771919061439e565b60405180910390f35b610782611716565b60405161078f919061439e565b60405180910390f35b6107b260048036038101906107ad9190614330565b611725565b6040516107bf9190614434565b60405180910390f35b6107e260048036038101906107dd919061466a565b611750565b6040516107ef91906141bd565b60405180910390f35b6108006117c9565b60405161080d91906142d8565b60405180910390f35b610830600480360381019061082b9190614330565b61186a565b60405161083d91906141bd565b60405180910390f35b61084e611898565b60405161085c929190614826565b60405180910390f35b61086d611909565b60405161087a919061422d565b60405180910390f35b61089d6004803603810190610898919061487b565b611910565b005b6108b960048036038101906108b491906148bb565b611926565b005b6108d560048036038101906108d09190614a2b565b61198e565b005b6108df6119ed565b6040516108ec919061422d565b60405180910390f35b61090f600480360381019061090a9190614330565b611a11565b60405161091c91906142d8565b60405180910390f35b61092d611adb565b60405161093a91906142d8565b60405180910390f35b61094b611b6d565b60405161095891906141f9565b60405180910390f35b610969611bee565b005b610973611c84565b604051610981929190614aae565b60405180910390f35b610992611cd8565b60405161099f919061422d565b60405180910390f35b6109c260048036038101906109bd919061466a565b611cfc565b005b6109cc611d46565b005b6109e860048036038101906109e39190614330565b611d5e565b005b610a0460048036038101906109ff9190614ad7565b611e5f565b005b610a0e611e89565b604051610a1b919061422d565b60405180910390f35b610a3e6004803603810190610a399190614b2a565b611ead565b604051610a4b91906141bd565b60405180910390f35b610a6e6004803603810190610a6991906147d9565b611f4f565b005b6000610a7b82611f90565b9050919050565b600062069780905090565b7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d36381565b60606000610abd61200a565b9050806000018054610ace90614b99565b80601f0160208091040260200160405190810160405280929190818152602001828054610afa90614b99565b8015610b475780601f10610b1c57610100808354040283529160200191610b47565b820191906000526020600020905b815481529060010190602001808311610b2a57829003601f168201915b505050505091505090565b6000610b5d82612032565b50610b67826120ba565b9050919050565b610b808282610b7b612105565b61210d565b5050565b6000801b610b918161211f565b610b99612133565b50565b6000806000838152602001908152602001600020549050919050565b6000600354905090565b60008484905090508087879050141580610bdf5750808383905014155b15610c16576040517fa8b3fce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610c9257610c85888883818110610c3757610c36614bca565b5b90506020020135878784818110610c5157610c50614bca565b5b90506020020135868685818110610c6b57610c6a614bca565b5b9050602002016020810190610c809190614729565b612140565b8080600101915050610c19565b508060036000828254610ca59190614c28565b9250508190555050505050505050565b80610cbf8161186a565b15610d0157806040517f82ded0a9000000000000000000000000000000000000000000000000000000008152600401610cf89190614434565b60405180910390fd5b610d0c84848461220e565b50505050565b600080610d1d612310565b905080600001600084815260200190815260200160002060010154915050919050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b6000801b8203610da0576040517f3fc3c27a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610daa8282612338565b5050565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c1610dd88161211f565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce782604051610e079190614434565b60405180910390a15050565b6000610e1d61235a565b90506000801b83148015610e635750610e346116de565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15610f2857600080610e73611c84565b91509150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580610eb95750610eb781612382565b155b80610eca5750610ec881612397565b155b15610f0c57806040517f19ca5ebb000000000000000000000000000000000000000000000000000000008152600401610f0391906141f9565b60405180910390fd5b8260000160146101000a81549065ffffffffffff021916905550505b610f3283836123ab565b505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610f618161211f565b610f69612426565b50565b610f878383836040518060200160405280600081525061198e565b505050565b610fbd7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848610fb8612105565b611750565b1561104e57600073ffffffffffffffffffffffffffffffffffffffff16610fe382612498565b73ffffffffffffffffffffffffffffffffffffffff160361103b57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016110329190614434565b60405180910390fd5b61104860008260006124e3565b50611063565b61106160008261105c612105565b6124e3565b505b50565b600080611071612501565b9050806001015491505090565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c181565b6060600180546110b190614b99565b80601f01602080910402602001604051908101604052809291908181526020018280546110dd90614b99565b801561112a5780601f106110ff5761010080835404028352916020019161112a565b820191906000526020600020905b81548152906001019060200180831161110d57829003601f168201915b5050505050905090565b60008061113f612529565b90508060000160009054906101000a900460ff1691505090565b6000611163612551565b905060008160000160089054906101000a900460ff1615905060008260000160009054906101000a900467ffffffffffffffff1690506000808267ffffffffffffffff161480156111b15750825b9050600060018367ffffffffffffffff161480156111e6575060003073ffffffffffffffffffffffffffffffffffffffff163b145b9050811580156111f4575080155b1561122b576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018560000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550831561127b5760018560000160086101000a81548160ff0219169083151502179055505b6112ef6040518060400160405280600481526020017f504f4150000000000000000000000000000000000000000000000000000000008152506040518060400160405280602081526020017f5468652050726f6f66206f6620417474656e64616e63652050726f746f636f6c815250612579565b6112f9878961258f565b611302866125a5565b60006040518060a001604052807f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681526020017f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881526020017f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81526020017f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d36381526020017f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c1815250905060005b60058110156114275761141a8282600581106113ef576113ee614bca565b5b60200201517f0f6ee822d2ee125e4ce6edbae6c10a76fa9fd4617e0399ab687226fa334421006125b9565b80806001019150506113d0565b50600060038190555050831561148d5760008560000160086101000a81548160ff0219169083151502179055507fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d260016040516114849190614cb5565b60405180910390a15b5050505050505050565b6000801b6114a48161211f565b6114ad82612603565b5050565b60006114bc82612032565b9050919050565b6000801b6114d08161211f565b6114d98261267e565b5050565b7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d3636115078161211f565b61150f6126e5565b816115198161186a565b61155a57806040517f03737d900000000000000000000000000000000000000000000000000000000081526004016115519190614434565b60405180910390fd5b61156383612726565b505050565b7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d3636115928161211f565b61159b8261277c565b5050565b6000806115aa61200a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361161e5760006040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401611615919061439e565b60405180910390fd5b8060030160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054915050919050565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c16116928161211f565b8282600191826116a3929190614e7d565b50505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6116d38161211f565b6116db612825565b50565b6000806116e961235a565b90508060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b60006117206116de565b905090565b600080611730612501565b905080600001600084815260200190815260200160002054915050919050565b60008061175b612310565b905080600001600085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b606060006117d561200a565b90508060010180546117e690614b99565b80601f016020809104026020016040519081016040528092919081815260200182805461181290614b99565b801561185f5780601f106118345761010080835404028352916020019161185f565b820191906000526020600020905b81548152906001019060200180831161184257829003601f168201915b505050505091505090565b600080611875612501565b905042816000016000858152602001908152602001600020541015915050919050565b60008060006118a561235a565b905080600101601a9054906101000a900465ffffffffffff1691506118c982612382565b80156118db57506118d982612397565b155b6118e757600080611900565b8060010160149054906101000a900465ffffffffffff16825b92509250509091565b6000801b81565b61192261191b612105565b8383612897565b5050565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c16119508161211f565b7f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c8383604051611981929190614f4d565b60405180910390a1505050565b816119988161186a565b156119da57806040517f82ded0a90000000000000000000000000000000000000000000000000000000081526004016119d19190614434565b60405180910390fd5b6119e685858585612a15565b5050505050565b7f0f6ee822d2ee125e4ce6edbae6c10a76fa9fd4617e0399ab687226fa3344210081565b6060611a1c82612032565b50611a25612a32565b611aa73073ffffffffffffffffffffffffffffffffffffffff1663127a5298856040518263ffffffff1660e01b8152600401611a619190614434565b602060405180830381865afa158015611a7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa29190614f8b565b612ac4565b611ab084612ac4565b6002604051602001611ac594939291906150c3565b6040516020818303038152906040529050919050565b606060028054611aea90614b99565b80601f0160208091040260200160405190810160405280929190818152602001828054611b1690614b99565b8015611b635780601f10611b3857610100808354040283529160200191611b63565b820191906000526020600020905b815481529060010190602001808311611b4657829003601f168201915b5050505050905090565b600080611b7861235a565b9050600081600101601a9054906101000a900465ffffffffffff169050611b9e81612382565b8015611baf5750611bae81612397565b5b611bcf5781600001601a9054906101000a900465ffffffffffff16611be7565b8160010160149054906101000a900465ffffffffffff165b9250505090565b6000611bf8611c84565b5090508073ffffffffffffffffffffffffffffffffffffffff16611c1a612105565b73ffffffffffffffffffffffffffffffffffffffff1614611c7957611c3d612105565b6040517fc22c8022000000000000000000000000000000000000000000000000000000008152600401611c70919061439e565b60405180910390fd5b611c81612b92565b50565b6000806000611c9161235a565b90508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160000160149054906101000a900465ffffffffffff1692509250509091565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6000801b8203611d38576040517f3fc3c27a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d428282612c72565b5050565b6000801b611d538161211f565b611d5b612c94565b50565b611d666126e5565b80611d708161186a565b15611db257806040517f82ded0a9000000000000000000000000000000000000000000000000000000008152600401611da99190614434565b60405180910390fd5b611dcc611dbe836114b1565b611dc6612105565b84612ca1565b158015611e075750611e057f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d363611e00612105565b611750565b155b15611e5257611e14612105565b826040517f2ddc489c000000000000000000000000000000000000000000000000000000008152600401611e4992919061510c565b60405180910390fd5b611e5b82612d62565b5050565b611e6a838383612140565b600160036000828254611e7d9190614c28565b92505081905550505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b600080611eb861200a565b90508060050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c1611f798161211f565b828260029182611f8a929190614e7d565b50505050565b60007f31498786000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612003575061200282612dc8565b5b9050919050565b60007f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300905090565b60008061203e83612498565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120b157826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016120a89190614434565b60405180910390fd5b80915050919050565b6000806120c561200a565b905080600401600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b600033905090565b61211a8383836001612e42565b505050565b6121308161212b612105565b613016565b50565b61213e600080613067565b565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661216a8161211f565b612174828461316e565b83600080858152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff1683857f8334f87aeaf76e52b061d93ee968e51fdd3ad53ca04e80271249227997aab3a060405160405180910390a4837f4b3711cd7ece062b0828c1b6e08d814a72d4c003383a016c833cbb1b45956e34846040516122009190614434565b60405180910390a250505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036122805760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401612277919061439e565b60405180910390fd5b6000612294838361228f612105565b6124e3565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461230a578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161230193929190615135565b60405180910390fd5b50505050565b60007f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800905090565b61234182610d12565b61234a8161211f565b612354838361318c565b50505050565b60007feef3dac4538c82c8ace4063ab0acd2d15cdb5883aa1dff7c2673abb3d8698400905090565b6000808265ffffffffffff1614159050919050565b6000428265ffffffffffff16109050919050565b6123b3612105565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612417576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124218282613267565b505050565b61242e6132f8565b6000612438612529565b905060008160000160006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa612480612105565b60405161248d919061439e565b60405180910390a150565b6000806124a361200a565b905080600201600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b60006124ed6126e5565b6124f8848484613338565b90509392505050565b60007fbd126dd2a6be31261d2bc770804fa46ffa8b92371cd3131388a6665931760900905090565b60007fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300905090565b60007ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00905090565b612581613565565b61258b82826135a5565b5050565b612597613565565b6125a182826135e2565b5050565b6125ad613565565b6125b6816136a2565b50565b6000801b82036125f5576040517f3fc3c27a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125ff82826136b6565b5050565b600061260d611b6d565b61261642613721565b612620919061516c565b905061262c828261377b565b8173ffffffffffffffffffffffffffffffffffffffff167f3377dc44241e779dd06afab5b788a35ca5f3b778836e2990bdb26a2a4b2e5ed68260405161267291906141f9565b60405180910390a25050565b60006126898261383f565b61269242613721565b61269c919061516c565b90506126a88282613067565b7ff1038c18cf84a56e432fdbfaf746924b7ea511dfe03a6506a0ceba4888788d9b82826040516126d9929190614826565b60405180910390a15050565b6126ed611134565b15612724576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612730612501565b905080600001600083815260200190815260200160002060009055817fe2babfd5e77285a3c3dbc4b25592cbe4a7a26e97a7ac63067a22ebdaa9b82add60405160405180910390a25050565b600081036127b6576040517f4143059f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006127c0612501565b90506000816001015490508282600101819055506127dc612105565b73ffffffffffffffffffffffffffffffffffffffff1683827f2a35095336ff94ac516ac526adb15bb38e136532e1fc5fd20aedbfae35fadeb960405160405180910390a4505050565b61282d6126e5565b6000612837612529565b905060018160000160006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861287f612105565b60405161288c919061439e565b60405180910390a150565b60006128a161200a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361291457826040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161290b919061439e565b60405180910390fd5b818160050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3184604051612a0791906141bd565b60405180910390a350505050565b612a20848484610cb5565b612a2c8484848461389e565b50505050565b606060018054612a4190614b99565b80601f0160208091040260200160405190810160405280929190818152602001828054612a6d90614b99565b8015612aba5780601f10612a8f57610100808354040283529160200191612aba565b820191906000526020600020905b815481529060010190602001808311612a9d57829003601f168201915b5050505050905090565b606060006001612ad384613a55565b01905060008167ffffffffffffffff811115612af257612af1614900565b5b6040519080825280601f01601f191660200182016040528015612b245781602001600182028036833780820191505090505b509050600082602001820190505b600115612b87578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612b7b57612b7a6151a6565b5b04945060008503612b32575b819350505050919050565b6000612b9c61235a565b9050600080612ba9611c84565b91509150612bb681612382565b1580612bc85750612bc681612397565b155b15612c0a57806040517f19ca5ebb000000000000000000000000000000000000000000000000000000008152600401612c0191906141f9565b60405180910390fd5b612c1e6000801b612c196116de565b613267565b50612c2c6000801b8361318c565b508260000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690558260000160146101000a81549065ffffffffffff0219169055505050565b612c7b82610d12565b612c848161211f565b612c8e8383613267565b50505050565b612c9f60008061377b565b565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015612d5957508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612d1a5750612d198484611ead565b5b80612d5857508273ffffffffffffffffffffffffffffffffffffffff16612d40836120ba565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b6000612d6c612501565b9050806001015442612d7e9190614c28565b81600001600084815260200190815260200160002081905550817f779fbee689bbd6f006ecb329206d35c7db7380f9837a8826fb8dc5cfcd3d33dd60405160405180910390a25050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612e3b5750612e3a82613ba8565b5b9050919050565b6000612e4c61200a565b90508180612e875750600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b15612fbb576000612e9785612032565b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015612f0257508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015612f155750612f138185611ead565b155b15612f5757836040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401612f4e919061439e565b60405180910390fd5b8215612fb957848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8481600401600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6130208282611750565b6130635780826040517fe2517d3f00000000000000000000000000000000000000000000000000000000815260040161305a9291906151d5565b60405180910390fd5b5050565b600061307161235a565b9050600081600101601a9054906101000a900465ffffffffffff16905061309781612382565b1561311a576130a581612397565b156130ec578160010160149054906101000a900465ffffffffffff1682600001601a6101000a81548165ffffffffffff021916908365ffffffffffff160217905550613119565b7f2b1fa2edafe6f7b9e97c1a9e0c3660e645beb2dcaa2d45bdbf9beaf5472e1ec560405160405180910390a15b5b838260010160146101000a81548165ffffffffffff021916908365ffffffffffff1602179055508282600101601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555050505050565b613188828260405180602001604052806000815250613c8a565b5050565b60008061319761235a565b90506000801b840361325457600073ffffffffffffffffffffffffffffffffffffffff166131c36116de565b73ffffffffffffffffffffffffffffffffffffffff1614613210576040517f3fc3c27a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b61325e8484613ca6565b91505092915050565b60008061327261235a565b90506000801b841480156132b857506132896116de565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b156132e5578060010160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b6132ef8484613da7565b91505092915050565b613300611134565b613336576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008061334361200a565b9050600061335085612498565b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461339257613391818587613ea9565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613425576133d4600086600080612e42565b60018260030160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146134aa5760018260030160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b8582600201600087815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480925050509392505050565b61356d613f6d565b6135a3576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6135ad613565565b60006135b761200a565b9050828160000190816135ca91906151fe565b50818160010190816135dc91906151fe565b50505050565b6135ea613565565b60006135f461235a565b9050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036136685760006040517fc22c802200000000000000000000000000000000000000000000000000000000815260040161365f919061439e565b60405180910390fd5b8281600001601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555061369c6000801b8361318c565b50505050565b6136aa613565565b6136b38161277c565b50565b60006136c0612310565b905060006136cd84610d12565b905082826000016000868152602001908152602001600020600101819055508281857fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff60405160405180910390a450505050565b600065ffffffffffff8016821115613773576030826040517f6dfcc65000000000000000000000000000000000000000000000000000000000815260040161376a929190615318565b60405180910390fd5b819050919050565b600061378561235a565b90506000613791611c84565b915050838260000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828260000160146101000a81548165ffffffffffff021916908365ffffffffffff16021790555061380781612382565b15613839577f8886ebfc4259abdbc16601dd8fb5678e54878f47b3c34836cfc51154a960510960405160405180910390a15b50505050565b60008061384a611b6d565b90508065ffffffffffff168365ffffffffffff161161387457828161386f9190615341565b613896565b6138958365ffffffffffff16613888610a82565b65ffffffffffff16613f8d565b5b915050919050565b60008373ffffffffffffffffffffffffffffffffffffffff163b1115613a4f578273ffffffffffffffffffffffffffffffffffffffff1663150b7a026138e2612105565b8685856040518563ffffffff1660e01b815260040161390494939291906153d0565b6020604051808303816000875af192505050801561394057506040513d601f19601f8201168201806040525081019061393d9190615431565b60015b6139c4573d8060008114613970576040519150601f19603f3d011682016040523d82523d6000602084013e613975565b606091505b5060008151036139bc57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016139b3919061439e565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614613a4d57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401613a44919061439e565b60405180910390fd5b505b50505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613ab3577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613aa957613aa86151a6565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613af0576d04ee2d6d415b85acef81000000008381613ae657613ae56151a6565b5b0492506020810190505b662386f26fc100008310613b1f57662386f26fc100008381613b1557613b146151a6565b5b0492506010810190505b6305f5e1008310613b48576305f5e1008381613b3e57613b3d6151a6565b5b0492506008810190505b6127108310613b6d576127108381613b6357613b626151a6565b5b0492506004810190505b60648310613b905760648381613b8657613b856151a6565b5b0492506002810190505b600a8310613b9f576001810190505b80915050919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613c7357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613c835750613c8282613fa6565b5b9050919050565b613c948383614010565b613ca1600084848461389e565b505050565b600080613cb1612310565b9050613cbd8484611750565b613d9b57600181600001600086815260200190815260200160002060000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550613d37612105565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001915050613da1565b60009150505b92915050565b600080613db2612310565b9050613dbe8484611750565b15613e9d57600081600001600086815260200190815260200160002060000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550613e39612105565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a46001915050613ea3565b60009150505b92915050565b613eb4838383612ca1565b613f6857600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613f2957806040517f7e273289000000000000000000000000000000000000000000000000000000008152600401613f209190614434565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401613f5f92919061510c565b60405180910390fd5b505050565b6000613f77612551565b60000160089054906101000a900460ff16905090565b6000818310613f9c5781613f9e565b825b905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036140825760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401614079919061439e565b60405180910390fd5b6000614090838360006124e3565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146141045760006040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016140fb919061439e565b60405180910390fd5b505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6141528161411d565b811461415d57600080fd5b50565b60008135905061416f81614149565b92915050565b60006020828403121561418b5761418a614113565b5b600061419984828501614160565b91505092915050565b60008115159050919050565b6141b7816141a2565b82525050565b60006020820190506141d260008301846141ae565b92915050565b600065ffffffffffff82169050919050565b6141f3816141d8565b82525050565b600060208201905061420e60008301846141ea565b92915050565b6000819050919050565b61422781614214565b82525050565b6000602082019050614242600083018461421e565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015614282578082015181840152602081019050614267565b60008484015250505050565b6000601f19601f8301169050919050565b60006142aa82614248565b6142b48185614253565b93506142c4818560208601614264565b6142cd8161428e565b840191505092915050565b600060208201905081810360008301526142f2818461429f565b905092915050565b6000819050919050565b61430d816142fa565b811461431857600080fd5b50565b60008135905061432a81614304565b92915050565b60006020828403121561434657614345614113565b5b60006143548482850161431b565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006143888261435d565b9050919050565b6143988161437d565b82525050565b60006020820190506143b3600083018461438f565b92915050565b6143c28161437d565b81146143cd57600080fd5b50565b6000813590506143df816143b9565b92915050565b600080604083850312156143fc576143fb614113565b5b600061440a858286016143d0565b925050602061441b8582860161431b565b9150509250929050565b61442e816142fa565b82525050565b60006020820190506144496000830184614425565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126144745761447361444f565b5b8235905067ffffffffffffffff81111561449157614490614454565b5b6020830191508360208202830111156144ad576144ac614459565b5b9250929050565b60008083601f8401126144ca576144c961444f565b5b8235905067ffffffffffffffff8111156144e7576144e6614454565b5b60208301915083602082028301111561450357614502614459565b5b9250929050565b6000806000806000806060878903121561452757614526614113565b5b600087013567ffffffffffffffff81111561454557614544614118565b5b61455189828a0161445e565b9650965050602087013567ffffffffffffffff81111561457457614573614118565b5b61458089828a0161445e565b9450945050604087013567ffffffffffffffff8111156145a3576145a2614118565b5b6145af89828a016144b4565b92509250509295509295509295565b6000806000606084860312156145d7576145d6614113565b5b60006145e5868287016143d0565b93505060206145f6868287016143d0565b92505060406146078682870161431b565b9150509250925092565b61461a81614214565b811461462557600080fd5b50565b60008135905061463781614611565b92915050565b60006020828403121561465357614652614113565b5b600061466184828501614628565b91505092915050565b6000806040838503121561468157614680614113565b5b600061468f85828601614628565b92505060206146a0858286016143d0565b9150509250929050565b6146b3816141d8565b81146146be57600080fd5b50565b6000813590506146d0816146aa565b92915050565b6000806000606084860312156146ef576146ee614113565b5b60006146fd868287016143d0565b935050602061470e868287016146c1565b925050604061471f8682870161431b565b9150509250925092565b60006020828403121561473f5761473e614113565b5b600061474d848285016143d0565b91505092915050565b60006020828403121561476c5761476b614113565b5b600061477a848285016146c1565b91505092915050565b60008083601f8401126147995761479861444f565b5b8235905067ffffffffffffffff8111156147b6576147b5614454565b5b6020830191508360018202830111156147d2576147d1614459565b5b9250929050565b600080602083850312156147f0576147ef614113565b5b600083013567ffffffffffffffff81111561480e5761480d614118565b5b61481a85828601614783565b92509250509250929050565b600060408201905061483b60008301856141ea565b61484860208301846141ea565b9392505050565b614858816141a2565b811461486357600080fd5b50565b6000813590506148758161484f565b92915050565b6000806040838503121561489257614891614113565b5b60006148a0858286016143d0565b92505060206148b185828601614866565b9150509250929050565b600080604083850312156148d2576148d1614113565b5b60006148e08582860161431b565b92505060206148f18582860161431b565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6149388261428e565b810181811067ffffffffffffffff8211171561495757614956614900565b5b80604052505050565b600061496a614109565b9050614976828261492f565b919050565b600067ffffffffffffffff82111561499657614995614900565b5b61499f8261428e565b9050602081019050919050565b82818337600083830152505050565b60006149ce6149c98461497b565b614960565b9050828152602081018484840111156149ea576149e96148fb565b5b6149f58482856149ac565b509392505050565b600082601f830112614a1257614a1161444f565b5b8135614a228482602086016149bb565b91505092915050565b60008060008060808587031215614a4557614a44614113565b5b6000614a53878288016143d0565b9450506020614a64878288016143d0565b9350506040614a758782880161431b565b925050606085013567ffffffffffffffff811115614a9657614a95614118565b5b614aa2878288016149fd565b91505092959194509250565b6000604082019050614ac3600083018561438f565b614ad060208301846141ea565b9392505050565b600080600060608486031215614af057614aef614113565b5b6000614afe8682870161431b565b9350506020614b0f8682870161431b565b9250506040614b20868287016143d0565b9150509250925092565b60008060408385031215614b4157614b40614113565b5b6000614b4f858286016143d0565b9250506020614b60858286016143d0565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614bb157607f821691505b602082108103614bc457614bc3614b6a565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614c33826142fa565b9150614c3e836142fa565b9250828201905080821115614c5657614c55614bf9565b5b92915050565b6000819050919050565b600067ffffffffffffffff82169050919050565b6000819050919050565b6000614c9f614c9a614c9584614c5c565b614c7a565b614c66565b9050919050565b614caf81614c84565b82525050565b6000602082019050614cca6000830184614ca6565b92915050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302614d3d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614d00565b614d478683614d00565b95508019841693508086168417925050509392505050565b6000614d7a614d75614d70846142fa565b614c7a565b6142fa565b9050919050565b6000819050919050565b614d9483614d5f565b614da8614da082614d81565b848454614d0d565b825550505050565b600090565b614dbd614db0565b614dc8818484614d8b565b505050565b5b81811015614dec57614de1600082614db5565b600181019050614dce565b5050565b601f821115614e3157614e0281614cdb565b614e0b84614cf0565b81016020851015614e1a578190505b614e2e614e2685614cf0565b830182614dcd565b50505b505050565b600082821c905092915050565b6000614e5460001984600802614e36565b1980831691505092915050565b6000614e6d8383614e43565b9150826002028217905092915050565b614e878383614cd0565b67ffffffffffffffff811115614ea057614e9f614900565b5b614eaa8254614b99565b614eb5828285614df0565b6000601f831160018114614ee45760008415614ed2578287013590505b614edc8582614e61565b865550614f44565b601f198416614ef286614cdb565b60005b82811015614f1a57848901358255600182019150602085019450602081019050614ef5565b86831015614f375784890135614f33601f891682614e43565b8355505b6001600288020188555050505b50505050505050565b6000604082019050614f626000830185614425565b614f6f6020830184614425565b9392505050565b600081519050614f8581614304565b92915050565b600060208284031215614fa157614fa0614113565b5b6000614faf84828501614f76565b91505092915050565b600081905092915050565b6000614fce82614248565b614fd88185614fb8565b9350614fe8818560208601614264565b80840191505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b600061502a600183614fb8565b915061503582614ff4565b600182019050919050565b6000815461504d81614b99565b6150578186614fb8565b945060018216600081146150725760018114615087576150ba565b60ff19831686528115158202860193506150ba565b61509085614cdb565b60005b838110156150b257815481890152600182019150602081019050615093565b838801955050505b50505092915050565b60006150cf8287614fc3565b91506150db8286614fc3565b91506150e68261501d565b91506150f28285614fc3565b91506150fe8284615040565b915081905095945050505050565b6000604082019050615121600083018561438f565b61512e6020830184614425565b9392505050565b600060608201905061514a600083018661438f565b6151576020830185614425565b615164604083018461438f565b949350505050565b6000615177826141d8565b9150615182836141d8565b9250828201905065ffffffffffff8111156151a05761519f614bf9565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006040820190506151ea600083018561438f565b6151f7602083018461421e565b9392505050565b61520782614248565b67ffffffffffffffff8111156152205761521f614900565b5b61522a8254614b99565b615235828285614df0565b600060209050601f8311600181146152685760008415615256578287015190505b6152608582614e61565b8655506152c8565b601f19841661527686614cdb565b60005b8281101561529e57848901518255600182019150602085019450602081019050615279565b868310156152bb57848901516152b7601f891682614e43565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b60006153026152fd6152f8846152d0565b614c7a565b6152da565b9050919050565b615312816152e7565b82525050565b600060408201905061532d6000830185615309565b61533a6020830184614425565b9392505050565b600061534c826141d8565b9150615357836141d8565b9250828203905065ffffffffffff81111561537557615374614bf9565b5b92915050565b600081519050919050565b600082825260208201905092915050565b60006153a28261537b565b6153ac8185615386565b93506153bc818560208601614264565b6153c58161428e565b840191505092915050565b60006080820190506153e5600083018761438f565b6153f2602083018661438f565b6153ff6040830185614425565b81810360608301526154118184615397565b905095945050505050565b60008151905061542b81614149565b92915050565b60006020828403121561544757615446614113565b5b60006154558482850161541c565b9150509291505056fea2646970667358221220c851c62872d8b981dbcd908a057bfc8022dacaef7633f373107863b1c2c1fcd864736f6c634300081c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103835760003560e01c80636ca2aa95116101de578063b88d4fde1161010f578063d5391393116100ad578063d890c8e21161007c578063d890c8e2146109ea578063e63ab1e914610a06578063e985e9c514610a24578063f0df844b14610a5457610383565b8063d53913931461098a578063d547741f146109a8578063d602b9fd146109c4578063d7a78db8146109ce57610383565b8063cc5b3105116100e9578063cc5b310514610925578063cc8463c814610943578063cefc142914610961578063cf6eefb71461096b57610383565b8063b88d4fde146108bb578063c6b54b3c146108d7578063c87b56dd146108f557610383565b806391d148541161017c578063a1eda53c11610156578063a1eda53c14610846578063a217fddf14610865578063a22cb46514610883578063a48301141461089f57610383565b806391d14854146107c857806395d89b41146107f8578063a08947991461081657610383565b80638456cb59116101b85780638456cb591461075257806384ef8ffc1461075c5780638da5cb5b1461077a57806390fdd8971461079857610383565b80636ca2aa95146106ea57806370a08231146107065780637e518ec81461073657610383565b80633190b9ea116102b85780635b2bd79e11610256578063634e93da11610230578063634e93da146106665780636352211e14610682578063649a5ec7146106b25780636623fc46146106ce57610383565b80635b2bd79e1461060e5780635c975abb1461062c5780635e813d2d1461064a57610383565b806342842e0e1161029257806342842e0e1461059a57806342966c68146105b6578063440991bd146105d2578063529470e8146105f057610383565b80633190b9ea1461055857806336568abe146105745780633f4ba83a1461059057610383565b8063127a52981161032557806323b872dd116102ff57806323b872dd146104d2578063248a9ca3146104ee578063282c51f31461051e5780632f2ff15d1461053c57610383565b8063127a52981461046857806318160ddd146104985780631cddf50a146104b657610383565b806306fdde031161036157806306fdde03146103f4578063081812fc14610412578063095ea7b3146104425780630aa6220b1461045e57610383565b806301ffc9a714610388578063022d63fb146103b857806306a85f0f146103d6575b600080fd5b6103a2600480360381019061039d9190614175565b610a70565b6040516103af91906141bd565b60405180910390f35b6103c0610a82565b6040516103cd91906141f9565b60405180910390f35b6103de610a8d565b6040516103eb919061422d565b60405180910390f35b6103fc610ab1565b60405161040991906142d8565b60405180910390f35b61042c60048036038101906104279190614330565b610b52565b604051610439919061439e565b60405180910390f35b61045c600480360381019061045791906143e5565b610b6e565b005b610466610b84565b005b610482600480360381019061047d9190614330565b610b9c565b60405161048f9190614434565b60405180910390f35b6104a0610bb8565b6040516104ad9190614434565b60405180910390f35b6104d060048036038101906104cb919061450a565b610bc2565b005b6104ec60048036038101906104e791906145be565b610cb5565b005b6105086004803603810190610503919061463d565b610d12565b604051610515919061422d565b60405180910390f35b610526610d40565b604051610533919061422d565b60405180910390f35b6105566004803603810190610551919061466a565b610d64565b005b610572600480360381019061056d9190614330565b610dae565b005b61058e6004803603810190610589919061466a565b610e13565b005b610598610f37565b005b6105b460048036038101906105af91906145be565b610f6c565b005b6105d060048036038101906105cb9190614330565b610f8c565b005b6105da611066565b6040516105e79190614434565b60405180910390f35b6105f861107e565b604051610605919061422d565b60405180910390f35b6106166110a2565b60405161062391906142d8565b60405180910390f35b610634611134565b60405161064191906141bd565b60405180910390f35b610664600480360381019061065f91906146d6565b611159565b005b610680600480360381019061067b9190614729565b611497565b005b61069c60048036038101906106979190614330565b6114b1565b6040516106a9919061439e565b60405180910390f35b6106cc60048036038101906106c79190614756565b6114c3565b005b6106e860048036038101906106e39190614330565b6114dd565b005b61070460048036038101906106ff9190614330565b611568565b005b610720600480360381019061071b9190614729565b61159f565b60405161072d9190614434565b60405180910390f35b610750600480360381019061074b91906147d9565b611668565b005b61075a6116a9565b005b6107646116de565b604051610771919061439e565b60405180910390f35b610782611716565b60405161078f919061439e565b60405180910390f35b6107b260048036038101906107ad9190614330565b611725565b6040516107bf9190614434565b60405180910390f35b6107e260048036038101906107dd919061466a565b611750565b6040516107ef91906141bd565b60405180910390f35b6108006117c9565b60405161080d91906142d8565b60405180910390f35b610830600480360381019061082b9190614330565b61186a565b60405161083d91906141bd565b60405180910390f35b61084e611898565b60405161085c929190614826565b60405180910390f35b61086d611909565b60405161087a919061422d565b60405180910390f35b61089d6004803603810190610898919061487b565b611910565b005b6108b960048036038101906108b491906148bb565b611926565b005b6108d560048036038101906108d09190614a2b565b61198e565b005b6108df6119ed565b6040516108ec919061422d565b60405180910390f35b61090f600480360381019061090a9190614330565b611a11565b60405161091c91906142d8565b60405180910390f35b61092d611adb565b60405161093a91906142d8565b60405180910390f35b61094b611b6d565b60405161095891906141f9565b60405180910390f35b610969611bee565b005b610973611c84565b604051610981929190614aae565b60405180910390f35b610992611cd8565b60405161099f919061422d565b60405180910390f35b6109c260048036038101906109bd919061466a565b611cfc565b005b6109cc611d46565b005b6109e860048036038101906109e39190614330565b611d5e565b005b610a0460048036038101906109ff9190614ad7565b611e5f565b005b610a0e611e89565b604051610a1b919061422d565b60405180910390f35b610a3e6004803603810190610a399190614b2a565b611ead565b604051610a4b91906141bd565b60405180910390f35b610a6e6004803603810190610a6991906147d9565b611f4f565b005b6000610a7b82611f90565b9050919050565b600062069780905090565b7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d36381565b60606000610abd61200a565b9050806000018054610ace90614b99565b80601f0160208091040260200160405190810160405280929190818152602001828054610afa90614b99565b8015610b475780601f10610b1c57610100808354040283529160200191610b47565b820191906000526020600020905b815481529060010190602001808311610b2a57829003601f168201915b505050505091505090565b6000610b5d82612032565b50610b67826120ba565b9050919050565b610b808282610b7b612105565b61210d565b5050565b6000801b610b918161211f565b610b99612133565b50565b6000806000838152602001908152602001600020549050919050565b6000600354905090565b60008484905090508087879050141580610bdf5750808383905014155b15610c16576040517fa8b3fce800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610c9257610c85888883818110610c3757610c36614bca565b5b90506020020135878784818110610c5157610c50614bca565b5b90506020020135868685818110610c6b57610c6a614bca565b5b9050602002016020810190610c809190614729565b612140565b8080600101915050610c19565b508060036000828254610ca59190614c28565b9250508190555050505050505050565b80610cbf8161186a565b15610d0157806040517f82ded0a9000000000000000000000000000000000000000000000000000000008152600401610cf89190614434565b60405180910390fd5b610d0c84848461220e565b50505050565b600080610d1d612310565b905080600001600084815260200190815260200160002060010154915050919050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b6000801b8203610da0576040517f3fc3c27a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610daa8282612338565b5050565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c1610dd88161211f565b7ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce782604051610e079190614434565b60405180910390a15050565b6000610e1d61235a565b90506000801b83148015610e635750610e346116de565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b15610f2857600080610e73611c84565b91509150600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141580610eb95750610eb781612382565b155b80610eca5750610ec881612397565b155b15610f0c57806040517f19ca5ebb000000000000000000000000000000000000000000000000000000008152600401610f0391906141f9565b60405180910390fd5b8260000160146101000a81549065ffffffffffff021916905550505b610f3283836123ab565b505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610f618161211f565b610f69612426565b50565b610f878383836040518060200160405280600081525061198e565b505050565b610fbd7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848610fb8612105565b611750565b1561104e57600073ffffffffffffffffffffffffffffffffffffffff16610fe382612498565b73ffffffffffffffffffffffffffffffffffffffff160361103b57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016110329190614434565b60405180910390fd5b61104860008260006124e3565b50611063565b61106160008261105c612105565b6124e3565b505b50565b600080611071612501565b9050806001015491505090565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c181565b6060600180546110b190614b99565b80601f01602080910402602001604051908101604052809291908181526020018280546110dd90614b99565b801561112a5780601f106110ff5761010080835404028352916020019161112a565b820191906000526020600020905b81548152906001019060200180831161110d57829003601f168201915b5050505050905090565b60008061113f612529565b90508060000160009054906101000a900460ff1691505090565b6000611163612551565b905060008160000160089054906101000a900460ff1615905060008260000160009054906101000a900467ffffffffffffffff1690506000808267ffffffffffffffff161480156111b15750825b9050600060018367ffffffffffffffff161480156111e6575060003073ffffffffffffffffffffffffffffffffffffffff163b145b9050811580156111f4575080155b1561122b576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018560000160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550831561127b5760018560000160086101000a81548160ff0219169083151502179055505b6112ef6040518060400160405280600481526020017f504f4150000000000000000000000000000000000000000000000000000000008152506040518060400160405280602081526020017f5468652050726f6f66206f6620417474656e64616e63652050726f746f636f6c815250612579565b6112f9878961258f565b611302866125a5565b60006040518060a001604052807f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681526020017f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881526020017f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81526020017f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d36381526020017f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c1815250905060005b60058110156114275761141a8282600581106113ef576113ee614bca565b5b60200201517f0f6ee822d2ee125e4ce6edbae6c10a76fa9fd4617e0399ab687226fa334421006125b9565b80806001019150506113d0565b50600060038190555050831561148d5760008560000160086101000a81548160ff0219169083151502179055507fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d260016040516114849190614cb5565b60405180910390a15b5050505050505050565b6000801b6114a48161211f565b6114ad82612603565b5050565b60006114bc82612032565b9050919050565b6000801b6114d08161211f565b6114d98261267e565b5050565b7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d3636115078161211f565b61150f6126e5565b816115198161186a565b61155a57806040517f03737d900000000000000000000000000000000000000000000000000000000081526004016115519190614434565b60405180910390fd5b61156383612726565b505050565b7f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d3636115928161211f565b61159b8261277c565b5050565b6000806115aa61200a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361161e5760006040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401611615919061439e565b60405180910390fd5b8060030160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054915050919050565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c16116928161211f565b8282600191826116a3929190614e7d565b50505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6116d38161211f565b6116db612825565b50565b6000806116e961235a565b90508060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b60006117206116de565b905090565b600080611730612501565b905080600001600084815260200190815260200160002054915050919050565b60008061175b612310565b905080600001600085815260200190815260200160002060000160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b606060006117d561200a565b90508060010180546117e690614b99565b80601f016020809104026020016040519081016040528092919081815260200182805461181290614b99565b801561185f5780601f106118345761010080835404028352916020019161185f565b820191906000526020600020905b81548152906001019060200180831161184257829003601f168201915b505050505091505090565b600080611875612501565b905042816000016000858152602001908152602001600020541015915050919050565b60008060006118a561235a565b905080600101601a9054906101000a900465ffffffffffff1691506118c982612382565b80156118db57506118d982612397565b155b6118e757600080611900565b8060010160149054906101000a900465ffffffffffff16825b92509250509091565b6000801b81565b61192261191b612105565b8383612897565b5050565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c16119508161211f565b7f6bd5c950a8d8df17f772f5af37cb3655737899cbf903264b9795592da439661c8383604051611981929190614f4d565b60405180910390a1505050565b816119988161186a565b156119da57806040517f82ded0a90000000000000000000000000000000000000000000000000000000081526004016119d19190614434565b60405180910390fd5b6119e685858585612a15565b5050505050565b7f0f6ee822d2ee125e4ce6edbae6c10a76fa9fd4617e0399ab687226fa3344210081565b6060611a1c82612032565b50611a25612a32565b611aa73073ffffffffffffffffffffffffffffffffffffffff1663127a5298856040518263ffffffff1660e01b8152600401611a619190614434565b602060405180830381865afa158015611a7e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa29190614f8b565b612ac4565b611ab084612ac4565b6002604051602001611ac594939291906150c3565b6040516020818303038152906040529050919050565b606060028054611aea90614b99565b80601f0160208091040260200160405190810160405280929190818152602001828054611b1690614b99565b8015611b635780601f10611b3857610100808354040283529160200191611b63565b820191906000526020600020905b815481529060010190602001808311611b4657829003601f168201915b5050505050905090565b600080611b7861235a565b9050600081600101601a9054906101000a900465ffffffffffff169050611b9e81612382565b8015611baf5750611bae81612397565b5b611bcf5781600001601a9054906101000a900465ffffffffffff16611be7565b8160010160149054906101000a900465ffffffffffff165b9250505090565b6000611bf8611c84565b5090508073ffffffffffffffffffffffffffffffffffffffff16611c1a612105565b73ffffffffffffffffffffffffffffffffffffffff1614611c7957611c3d612105565b6040517fc22c8022000000000000000000000000000000000000000000000000000000008152600401611c70919061439e565b60405180910390fd5b611c81612b92565b50565b6000806000611c9161235a565b90508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160000160149054906101000a900465ffffffffffff1692509250509091565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b6000801b8203611d38576040517f3fc3c27a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d428282612c72565b5050565b6000801b611d538161211f565b611d5b612c94565b50565b611d666126e5565b80611d708161186a565b15611db257806040517f82ded0a9000000000000000000000000000000000000000000000000000000008152600401611da99190614434565b60405180910390fd5b611dcc611dbe836114b1565b611dc6612105565b84612ca1565b158015611e075750611e057f92de27771f92d6942691d73358b3a4673e4880de8356f8f2cf452be87e02d363611e00612105565b611750565b155b15611e5257611e14612105565b826040517f2ddc489c000000000000000000000000000000000000000000000000000000008152600401611e4992919061510c565b60405180910390fd5b611e5b82612d62565b5050565b611e6a838383612140565b600160036000828254611e7d9190614c28565b92505081905550505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b600080611eb861200a565b90508060050160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1691505092915050565b7f21e141d29efe528175baa3d6b347407f49288a1a3c0aebcc3160cd2b50b2a9c1611f798161211f565b828260029182611f8a929190614e7d565b50505050565b60007f31498786000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612003575061200282612dc8565b5b9050919050565b60007f80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300905090565b60008061203e83612498565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036120b157826040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016120a89190614434565b60405180910390fd5b80915050919050565b6000806120c561200a565b905080600401600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b600033905090565b61211a8383836001612e42565b505050565b6121308161212b612105565b613016565b50565b61213e600080613067565b565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661216a8161211f565b612174828461316e565b83600080858152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff1683857f8334f87aeaf76e52b061d93ee968e51fdd3ad53ca04e80271249227997aab3a060405160405180910390a4837f4b3711cd7ece062b0828c1b6e08d814a72d4c003383a016c833cbb1b45956e34846040516122009190614434565b60405180910390a250505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036122805760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401612277919061439e565b60405180910390fd5b6000612294838361228f612105565b6124e3565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461230a578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161230193929190615135565b60405180910390fd5b50505050565b60007f02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800905090565b61234182610d12565b61234a8161211f565b612354838361318c565b50505050565b60007feef3dac4538c82c8ace4063ab0acd2d15cdb5883aa1dff7c2673abb3d8698400905090565b6000808265ffffffffffff1614159050919050565b6000428265ffffffffffff16109050919050565b6123b3612105565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614612417576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6124218282613267565b505050565b61242e6132f8565b6000612438612529565b905060008160000160006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa612480612105565b60405161248d919061439e565b60405180910390a150565b6000806124a361200a565b905080600201600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b60006124ed6126e5565b6124f8848484613338565b90509392505050565b60007fbd126dd2a6be31261d2bc770804fa46ffa8b92371cd3131388a6665931760900905090565b60007fcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300905090565b60007ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00905090565b612581613565565b61258b82826135a5565b5050565b612597613565565b6125a182826135e2565b5050565b6125ad613565565b6125b6816136a2565b50565b6000801b82036125f5576040517f3fc3c27a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125ff82826136b6565b5050565b600061260d611b6d565b61261642613721565b612620919061516c565b905061262c828261377b565b8173ffffffffffffffffffffffffffffffffffffffff167f3377dc44241e779dd06afab5b788a35ca5f3b778836e2990bdb26a2a4b2e5ed68260405161267291906141f9565b60405180910390a25050565b60006126898261383f565b61269242613721565b61269c919061516c565b90506126a88282613067565b7ff1038c18cf84a56e432fdbfaf746924b7ea511dfe03a6506a0ceba4888788d9b82826040516126d9929190614826565b60405180910390a15050565b6126ed611134565b15612724576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6000612730612501565b905080600001600083815260200190815260200160002060009055817fe2babfd5e77285a3c3dbc4b25592cbe4a7a26e97a7ac63067a22ebdaa9b82add60405160405180910390a25050565b600081036127b6576040517f4143059f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006127c0612501565b90506000816001015490508282600101819055506127dc612105565b73ffffffffffffffffffffffffffffffffffffffff1683827f2a35095336ff94ac516ac526adb15bb38e136532e1fc5fd20aedbfae35fadeb960405160405180910390a4505050565b61282d6126e5565b6000612837612529565b905060018160000160006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861287f612105565b60405161288c919061439e565b60405180910390a150565b60006128a161200a565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361291457826040517f5b08ba1800000000000000000000000000000000000000000000000000000000815260040161290b919061439e565b60405180910390fd5b818160050160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3184604051612a0791906141bd565b60405180910390a350505050565b612a20848484610cb5565b612a2c8484848461389e565b50505050565b606060018054612a4190614b99565b80601f0160208091040260200160405190810160405280929190818152602001828054612a6d90614b99565b8015612aba5780601f10612a8f57610100808354040283529160200191612aba565b820191906000526020600020905b815481529060010190602001808311612a9d57829003601f168201915b5050505050905090565b606060006001612ad384613a55565b01905060008167ffffffffffffffff811115612af257612af1614900565b5b6040519080825280601f01601f191660200182016040528015612b245781602001600182028036833780820191505090505b509050600082602001820190505b600115612b87578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612b7b57612b7a6151a6565b5b04945060008503612b32575b819350505050919050565b6000612b9c61235a565b9050600080612ba9611c84565b91509150612bb681612382565b1580612bc85750612bc681612397565b155b15612c0a57806040517f19ca5ebb000000000000000000000000000000000000000000000000000000008152600401612c0191906141f9565b60405180910390fd5b612c1e6000801b612c196116de565b613267565b50612c2c6000801b8361318c565b508260000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690558260000160146101000a81549065ffffffffffff0219169055505050565b612c7b82610d12565b612c848161211f565b612c8e8383613267565b50505050565b612c9f60008061377b565b565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015612d5957508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612d1a5750612d198484611ead565b5b80612d5857508273ffffffffffffffffffffffffffffffffffffffff16612d40836120ba565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b6000612d6c612501565b9050806001015442612d7e9190614c28565b81600001600084815260200190815260200160002081905550817f779fbee689bbd6f006ecb329206d35c7db7380f9837a8826fb8dc5cfcd3d33dd60405160405180910390a25050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612e3b5750612e3a82613ba8565b5b9050919050565b6000612e4c61200a565b90508180612e875750600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b15612fbb576000612e9785612032565b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614158015612f0257508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015612f155750612f138185611ead565b155b15612f5757836040517fa9fbf51f000000000000000000000000000000000000000000000000000000008152600401612f4e919061439e565b60405180910390fd5b8215612fb957848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8481600401600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050565b6130208282611750565b6130635780826040517fe2517d3f00000000000000000000000000000000000000000000000000000000815260040161305a9291906151d5565b60405180910390fd5b5050565b600061307161235a565b9050600081600101601a9054906101000a900465ffffffffffff16905061309781612382565b1561311a576130a581612397565b156130ec578160010160149054906101000a900465ffffffffffff1682600001601a6101000a81548165ffffffffffff021916908365ffffffffffff160217905550613119565b7f2b1fa2edafe6f7b9e97c1a9e0c3660e645beb2dcaa2d45bdbf9beaf5472e1ec560405160405180910390a15b5b838260010160146101000a81548165ffffffffffff021916908365ffffffffffff1602179055508282600101601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555050505050565b613188828260405180602001604052806000815250613c8a565b5050565b60008061319761235a565b90506000801b840361325457600073ffffffffffffffffffffffffffffffffffffffff166131c36116de565b73ffffffffffffffffffffffffffffffffffffffff1614613210576040517f3fc3c27a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b61325e8484613ca6565b91505092915050565b60008061327261235a565b90506000801b841480156132b857506132896116de565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b156132e5578060010160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b6132ef8484613da7565b91505092915050565b613300611134565b613336576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60008061334361200a565b9050600061335085612498565b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461339257613391818587613ea9565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613425576133d4600086600080612e42565b60018260030160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146134aa5760018260030160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b8582600201600087815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480925050509392505050565b61356d613f6d565b6135a3576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6135ad613565565b60006135b761200a565b9050828160000190816135ca91906151fe565b50818160010190816135dc91906151fe565b50505050565b6135ea613565565b60006135f461235a565b9050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036136685760006040517fc22c802200000000000000000000000000000000000000000000000000000000815260040161365f919061439e565b60405180910390fd5b8281600001601a6101000a81548165ffffffffffff021916908365ffffffffffff16021790555061369c6000801b8361318c565b50505050565b6136aa613565565b6136b38161277c565b50565b60006136c0612310565b905060006136cd84610d12565b905082826000016000868152602001908152602001600020600101819055508281857fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff60405160405180910390a450505050565b600065ffffffffffff8016821115613773576030826040517f6dfcc65000000000000000000000000000000000000000000000000000000000815260040161376a929190615318565b60405180910390fd5b819050919050565b600061378561235a565b90506000613791611c84565b915050838260000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550828260000160146101000a81548165ffffffffffff021916908365ffffffffffff16021790555061380781612382565b15613839577f8886ebfc4259abdbc16601dd8fb5678e54878f47b3c34836cfc51154a960510960405160405180910390a15b50505050565b60008061384a611b6d565b90508065ffffffffffff168365ffffffffffff161161387457828161386f9190615341565b613896565b6138958365ffffffffffff16613888610a82565b65ffffffffffff16613f8d565b5b915050919050565b60008373ffffffffffffffffffffffffffffffffffffffff163b1115613a4f578273ffffffffffffffffffffffffffffffffffffffff1663150b7a026138e2612105565b8685856040518563ffffffff1660e01b815260040161390494939291906153d0565b6020604051808303816000875af192505050801561394057506040513d601f19601f8201168201806040525081019061393d9190615431565b60015b6139c4573d8060008114613970576040519150601f19603f3d011682016040523d82523d6000602084013e613975565b606091505b5060008151036139bc57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016139b3919061439e565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614613a4d57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401613a44919061439e565b60405180910390fd5b505b50505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613ab3577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613aa957613aa86151a6565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613af0576d04ee2d6d415b85acef81000000008381613ae657613ae56151a6565b5b0492506020810190505b662386f26fc100008310613b1f57662386f26fc100008381613b1557613b146151a6565b5b0492506010810190505b6305f5e1008310613b48576305f5e1008381613b3e57613b3d6151a6565b5b0492506008810190505b6127108310613b6d576127108381613b6357613b626151a6565b5b0492506004810190505b60648310613b905760648381613b8657613b856151a6565b5b0492506002810190505b600a8310613b9f576001810190505b80915050919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613c7357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613c835750613c8282613fa6565b5b9050919050565b613c948383614010565b613ca1600084848461389e565b505050565b600080613cb1612310565b9050613cbd8484611750565b613d9b57600181600001600086815260200190815260200160002060000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550613d37612105565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001915050613da1565b60009150505b92915050565b600080613db2612310565b9050613dbe8484611750565b15613e9d57600081600001600086815260200190815260200160002060000160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550613e39612105565b73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16857ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a46001915050613ea3565b60009150505b92915050565b613eb4838383612ca1565b613f6857600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603613f2957806040517f7e273289000000000000000000000000000000000000000000000000000000008152600401613f209190614434565b60405180910390fd5b81816040517f177e802f000000000000000000000000000000000000000000000000000000008152600401613f5f92919061510c565b60405180910390fd5b505050565b6000613f77612551565b60000160089054906101000a900460ff16905090565b6000818310613f9c5781613f9e565b825b905092915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036140825760006040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401614079919061439e565b60405180910390fd5b6000614090838360006124e3565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146141045760006040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016140fb919061439e565b60405180910390fd5b505050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6141528161411d565b811461415d57600080fd5b50565b60008135905061416f81614149565b92915050565b60006020828403121561418b5761418a614113565b5b600061419984828501614160565b91505092915050565b60008115159050919050565b6141b7816141a2565b82525050565b60006020820190506141d260008301846141ae565b92915050565b600065ffffffffffff82169050919050565b6141f3816141d8565b82525050565b600060208201905061420e60008301846141ea565b92915050565b6000819050919050565b61422781614214565b82525050565b6000602082019050614242600083018461421e565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015614282578082015181840152602081019050614267565b60008484015250505050565b6000601f19601f8301169050919050565b60006142aa82614248565b6142b48185614253565b93506142c4818560208601614264565b6142cd8161428e565b840191505092915050565b600060208201905081810360008301526142f2818461429f565b905092915050565b6000819050919050565b61430d816142fa565b811461431857600080fd5b50565b60008135905061432a81614304565b92915050565b60006020828403121561434657614345614113565b5b60006143548482850161431b565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006143888261435d565b9050919050565b6143988161437d565b82525050565b60006020820190506143b3600083018461438f565b92915050565b6143c28161437d565b81146143cd57600080fd5b50565b6000813590506143df816143b9565b92915050565b600080604083850312156143fc576143fb614113565b5b600061440a858286016143d0565b925050602061441b8582860161431b565b9150509250929050565b61442e816142fa565b82525050565b60006020820190506144496000830184614425565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126144745761447361444f565b5b8235905067ffffffffffffffff81111561449157614490614454565b5b6020830191508360208202830111156144ad576144ac614459565b5b9250929050565b60008083601f8401126144ca576144c961444f565b5b8235905067ffffffffffffffff8111156144e7576144e6614454565b5b60208301915083602082028301111561450357614502614459565b5b9250929050565b6000806000806000806060878903121561452757614526614113565b5b600087013567ffffffffffffffff81111561454557614544614118565b5b61455189828a0161445e565b9650965050602087013567ffffffffffffffff81111561457457614573614118565b5b61458089828a0161445e565b9450945050604087013567ffffffffffffffff8111156145a3576145a2614118565b5b6145af89828a016144b4565b92509250509295509295509295565b6000806000606084860312156145d7576145d6614113565b5b60006145e5868287016143d0565b93505060206145f6868287016143d0565b92505060406146078682870161431b565b9150509250925092565b61461a81614214565b811461462557600080fd5b50565b60008135905061463781614611565b92915050565b60006020828403121561465357614652614113565b5b600061466184828501614628565b91505092915050565b6000806040838503121561468157614680614113565b5b600061468f85828601614628565b92505060206146a0858286016143d0565b9150509250929050565b6146b3816141d8565b81146146be57600080fd5b50565b6000813590506146d0816146aa565b92915050565b6000806000606084860312156146ef576146ee614113565b5b60006146fd868287016143d0565b935050602061470e868287016146c1565b925050604061471f8682870161431b565b9150509250925092565b60006020828403121561473f5761473e614113565b5b600061474d848285016143d0565b91505092915050565b60006020828403121561476c5761476b614113565b5b600061477a848285016146c1565b91505092915050565b60008083601f8401126147995761479861444f565b5b8235905067ffffffffffffffff8111156147b6576147b5614454565b5b6020830191508360018202830111156147d2576147d1614459565b5b9250929050565b600080602083850312156147f0576147ef614113565b5b600083013567ffffffffffffffff81111561480e5761480d614118565b5b61481a85828601614783565b92509250509250929050565b600060408201905061483b60008301856141ea565b61484860208301846141ea565b9392505050565b614858816141a2565b811461486357600080fd5b50565b6000813590506148758161484f565b92915050565b6000806040838503121561489257614891614113565b5b60006148a0858286016143d0565b92505060206148b185828601614866565b9150509250929050565b600080604083850312156148d2576148d1614113565b5b60006148e08582860161431b565b92505060206148f18582860161431b565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6149388261428e565b810181811067ffffffffffffffff8211171561495757614956614900565b5b80604052505050565b600061496a614109565b9050614976828261492f565b919050565b600067ffffffffffffffff82111561499657614995614900565b5b61499f8261428e565b9050602081019050919050565b82818337600083830152505050565b60006149ce6149c98461497b565b614960565b9050828152602081018484840111156149ea576149e96148fb565b5b6149f58482856149ac565b509392505050565b600082601f830112614a1257614a1161444f565b5b8135614a228482602086016149bb565b91505092915050565b60008060008060808587031215614a4557614a44614113565b5b6000614a53878288016143d0565b9450506020614a64878288016143d0565b9350506040614a758782880161431b565b925050606085013567ffffffffffffffff811115614a9657614a95614118565b5b614aa2878288016149fd565b91505092959194509250565b6000604082019050614ac3600083018561438f565b614ad060208301846141ea565b9392505050565b600080600060608486031215614af057614aef614113565b5b6000614afe8682870161431b565b9350506020614b0f8682870161431b565b9250506040614b20868287016143d0565b9150509250925092565b60008060408385031215614b4157614b40614113565b5b6000614b4f858286016143d0565b9250506020614b60858286016143d0565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614bb157607f821691505b602082108103614bc457614bc3614b6a565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614c33826142fa565b9150614c3e836142fa565b9250828201905080821115614c5657614c55614bf9565b5b92915050565b6000819050919050565b600067ffffffffffffffff82169050919050565b6000819050919050565b6000614c9f614c9a614c9584614c5c565b614c7a565b614c66565b9050919050565b614caf81614c84565b82525050565b6000602082019050614cca6000830184614ca6565b92915050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302614d3d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614d00565b614d478683614d00565b95508019841693508086168417925050509392505050565b6000614d7a614d75614d70846142fa565b614c7a565b6142fa565b9050919050565b6000819050919050565b614d9483614d5f565b614da8614da082614d81565b848454614d0d565b825550505050565b600090565b614dbd614db0565b614dc8818484614d8b565b505050565b5b81811015614dec57614de1600082614db5565b600181019050614dce565b5050565b601f821115614e3157614e0281614cdb565b614e0b84614cf0565b81016020851015614e1a578190505b614e2e614e2685614cf0565b830182614dcd565b50505b505050565b600082821c905092915050565b6000614e5460001984600802614e36565b1980831691505092915050565b6000614e6d8383614e43565b9150826002028217905092915050565b614e878383614cd0565b67ffffffffffffffff811115614ea057614e9f614900565b5b614eaa8254614b99565b614eb5828285614df0565b6000601f831160018114614ee45760008415614ed2578287013590505b614edc8582614e61565b865550614f44565b601f198416614ef286614cdb565b60005b82811015614f1a57848901358255600182019150602085019450602081019050614ef5565b86831015614f375784890135614f33601f891682614e43565b8355505b6001600288020188555050505b50505050505050565b6000604082019050614f626000830185614425565b614f6f6020830184614425565b9392505050565b600081519050614f8581614304565b92915050565b600060208284031215614fa157614fa0614113565b5b6000614faf84828501614f76565b91505092915050565b600081905092915050565b6000614fce82614248565b614fd88185614fb8565b9350614fe8818560208601614264565b80840191505092915050565b7f2f00000000000000000000000000000000000000000000000000000000000000600082015250565b600061502a600183614fb8565b915061503582614ff4565b600182019050919050565b6000815461504d81614b99565b6150578186614fb8565b945060018216600081146150725760018114615087576150ba565b60ff19831686528115158202860193506150ba565b61509085614cdb565b60005b838110156150b257815481890152600182019150602081019050615093565b838801955050505b50505092915050565b60006150cf8287614fc3565b91506150db8286614fc3565b91506150e68261501d565b91506150f28285614fc3565b91506150fe8284615040565b915081905095945050505050565b6000604082019050615121600083018561438f565b61512e6020830184614425565b9392505050565b600060608201905061514a600083018661438f565b6151576020830185614425565b615164604083018461438f565b949350505050565b6000615177826141d8565b9150615182836141d8565b9250828201905065ffffffffffff8111156151a05761519f614bf9565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006040820190506151ea600083018561438f565b6151f7602083018461421e565b9392505050565b61520782614248565b67ffffffffffffffff8111156152205761521f614900565b5b61522a8254614b99565b615235828285614df0565b600060209050601f8311600181146152685760008415615256578287015190505b6152608582614e61565b8655506152c8565b601f19841661527686614cdb565b60005b8281101561529e57848901518255600182019150602085019450602081019050615279565b868310156152bb57848901516152b7601f891682614e43565b8355505b6001600288020188555050505b505050505050565b6000819050919050565b600060ff82169050919050565b60006153026152fd6152f8846152d0565b614c7a565b6152da565b9050919050565b615312816152e7565b82525050565b600060408201905061532d6000830185615309565b61533a6020830184614425565b9392505050565b600061534c826141d8565b9150615357836141d8565b9250828203905065ffffffffffff81111561537557615374614bf9565b5b92915050565b600081519050919050565b600082825260208201905092915050565b60006153a28261537b565b6153ac8185615386565b93506153bc818560208601614264565b6153c58161428e565b840191505092915050565b60006080820190506153e5600083018761438f565b6153f2602083018661438f565b6153ff6040830185614425565b81810360608301526154118184615397565b905095945050505050565b60008151905061542b81614149565b92915050565b60006020828403121561544757615446614113565b5b60006154558482850161541c565b9150509291505056fea2646970667358221220c851c62872d8b981dbcd908a057bfc8022dacaef7633f373107863b1c2c1fcd864736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.