APE Price: $1.13 (+1.12%)

Contract Diff Checker

Contract Name:
Wrapped721

Contract Source Code:

File 1 of 1 : Wrapped721

// SPDX-License-Identifier: MIT
pragma solidity <0.9.0 >=0.8.4 ^0.8.1 ^0.8.2;

// node_modules/@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC165.sol

/**
* @dev Required interface of an ERC165 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*   Note: the ERC-165 identifier for this interface is 0x01ffc9a7.
*/
interface IERC165 {
  // **************************************
  // *****            VIEW            *****
  // **************************************
    /// @dev Returns if a contract implements an interface.
    ///   Interface identification is specified in ERC-165. This function uses less than 30,000 gas.
    function supportsInterface(bytes4 interfaceId_) external view returns (bool);
  // **************************************
}

// node_modules/@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC173.sol

// import "./IERC165.sol";

/**
* @dev Required interface of an ERC173 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-173[EIP].
*   Note: the ERC-165 identifier for this interface is 0x7f5828d0.
*/
interface IERC173 /* is IERC165 */ {
  // **************************************
  // *****           ERRORS           *****
  // **************************************
    /// @dev Thrown when `operator` is not the contract owner.
    /// 
    /// @param operator address trying to use a function reserved to contract owner without authorization
    error IERC173_NOT_OWNER(address operator);
  // **************************************

  // **************************************
  // *****           EVENTS           *****
  // **************************************
    /// @dev This emits when ownership of a contract changes.
    /// 
    /// @param previousOwner the previous contract owner
    /// @param newOwner the new contract owner
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
  // **************************************

  // **************************************
  // *****       CONTRACT_OWNER       *****
  // **************************************
    /// @dev Set the address of the new owner of the contract.
    ///   Set `newOwner_` to address(0) to renounce any ownership.
    function transferOwnership(address newOwner_) external; 
  // **************************************

  // **************************************
  // *****            VIEW            *****
  // **************************************
    /// @dev Returns the address of the owner.
    function owner() external view returns(address);
  // **************************************
}

// node_modules/@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC2981.sol

// import "./IERC165.sol";

/**
* @dev Required interface of an ERC2981 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-2981[EIP].
*   Note: the ERC-165 identifier for this interface is 0x2a55205a.
*/
interface IERC2981 /* is IERC165 */ {
  // **************************************
  // *****           ERRORS           *****
  // **************************************
    /// @dev Thrown when the desired royalty rate is higher than 10,000
    error IERC2981_INVALID_ROYALTIES();
  // **************************************

  // **************************************
  // *****            VIEW            *****
  // **************************************
    /// @dev Called with the sale price to determine how much royalty is owed and to whom.
    function royaltyInfo(uint256 tokenId_, uint256 salePrice_)
    external view returns (address receiver, uint256 royaltyAmount);
  // **************************************
}

// node_modules/@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721.sol

// import "./IERC165.sol";

/**
* @dev Required interface of an ERC721 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-721[EIP].
*   Note: the ERC-165 identifier for this interface is 0x80ac58cd.
*/
interface IERC721 /* is IERC165 */ {
  // **************************************
  // *****           ERRORS           *****
  // **************************************
    /// @dev Thrown when `operator` is not allowed to manage `tokenId`.
    /// 
    /// @param operator address trying to manage the token
    /// @param tokenId identifier of the NFT being referenced
    error IERC721_CALLER_NOT_APPROVED(address operator, uint256 tokenId);
    /// @dev Thrown when user tries to approve themselves for managing a token they own.
    error IERC721_INVALID_APPROVAL();
    /// @dev Thrown when a token is being transferred to a contract unable to handle it or the zero address.
    /// 
    /// @param receiver address unable to receive the token
    error IERC721_INVALID_RECEIVER(address receiver);
    /// @dev Thrown when checking ownership of the wrong token owner.
    error IERC721_INVALID_TOKEN_OWNER();
    /// @dev Thrown when the requested token doesn"t exist.
    /// 
    /// @param tokenId identifier of the NFT being referenced
    error IERC721_NONEXISTANT_TOKEN(uint256 tokenId);
  // **************************************

  // **************************************
  // *****           EVENTS           *****
  // **************************************
    /// @dev This emits when the approved address for an NFT is changed or reaffirmed.
    ///   The zero address indicates there is no approved address.
    ///   When a Transfer event emits, this also indicates that the approved address for that NFT (if any) is reset to none.
    /// 
    /// @param owner address that owns the token
    /// @param approved address that is allowed to manage the token
    /// @param tokenId identifier of the token being approved
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    /// @dev This emits when an operator is enabled or disabled for an owner. The operator can manage all NFTs of the owner.
    /// 
    /// @param owner address that owns the tokens
    /// @param operator address that is allowed or not to manage the tokens
    /// @param approved whether the operator is allowed or not
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
    /// @dev This emits when ownership of any NFT changes by any mechanism.
    ///   This event emits when NFTs are created (`from` == 0) and destroyed (`to` == 0).
    ///   Exception: during contract creation, any number of NFTs may be created and assigned without emitting Transfer.
    ///   At the time of any transfer, the approved address for that NFT (if any) is reset to none.
    /// 
    /// @param from address the token is being transferred from
    /// @param to address the token is being transferred to
    /// @param tokenId identifier of the token being transferred
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
  // **************************************

  // **************************************
  // *****           PUBLIC           *****
  // **************************************
    /// @notice Change or reaffirm the approved address for an NFT
    /// @dev The zero address indicates there is no approved address.
    ///   Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner.
    function approve(address approved_, uint256 tokenId_) external;
    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this NFT.
    ///   Throws if `from_` is not the current owner.
    ///   Throws if `to_` is the zero address.
    ///   Throws if `tokenId_` is not a valid NFT.
    ///   When transfer is complete, this function checks if `to_` is a smart contract (code size > 0).
    ///   If so, it calls {onERC721Received} on `to_` and throws if the return value is not
    ///   `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
    function safeTransferFrom(address from_, address to_, uint256 tokenId_, bytes calldata data_) external;
    /// @notice Transfers the ownership of an NFT from one address to another address
    /// @dev This works identically to the other function with an extra data parameter,
    ///   except this function just sets data to "".
    function safeTransferFrom(address from_, address to_, uint256 tokenId_) external;
    /// @notice Enable or disable approval for a third party ("operator") to manage all of `msg.sender`'s assets.
    /// @dev Emits the ApprovalForAll event. The contract MUST allow multiple operators per owner.
    function setApprovalForAll(address operator_, bool approved_) external;
    /// @notice Transfer ownership of an NFT.
    ///   The caller is responsible to confirm that `to_` is capable of receiving nfts or
    ///   else they may be permanently lost
    /// @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved address for this NFT.
    ///   Throws if `from_` is not the current owner.
    ///   Throws if `to_` is the zero address.
    ///   Throws if `tokenId_` is not a valid NFT.
    function transferFrom(address from_, address to_, uint256 tokenId_) external;
  // **************************************

  // **************************************
  // *****            VIEW            *****
  // **************************************
    /// @notice Count all NFTs assigned to an owner
    /// @dev NFTs assigned to the zero address are considered invalid. Throws for queries about the zero address.
    function balanceOf(address owner_) external view returns (uint256);
    /// @notice Get the approved address for a single NFT
    /// @dev Throws if `tokenId_` is not a valid NFT.
    function getApproved(uint256 tokenId_) external view returns (address);
    /// @notice Query if an address is an authorized operator for another address
    function isApprovedForAll(address owner_, address operator_) external view returns (bool);
    /// @notice Find the owner of an NFT
    /// @dev NFTs assigned to zero address are considered invalid, and queries
    ///  about them do throw.
    function ownerOf(uint256 tokenId_) external view returns (address);
  // **************************************
}

// node_modules/@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721Enumerable.sol

// import "./IERC721.sol";

/**
* @dev Required interface of an ERC721 compliant contract, optional enumeration extension, as defined in the
* https://eips.ethereum.org/EIPS/eip-721[EIP].
*   Note: the ERC-165 identifier for this interface is 0x780e9d63.
*/
interface IERC721Enumerable /* is IERC721 */ {
  // **************************************
  // *****           ERRORS           *****
  // **************************************
    /// @dev Thrown when trying to get the token at an index that doesn"t exist.
    /// 
    /// @param index the inexistant index
    error IERC721Enumerable_INDEX_OUT_OF_BOUNDS(uint256 index);
    /// @dev Thrown when trying to get the token owned by `tokenOwner` at an index that doesn"t exist.
    /// 
    /// @param index the inexistant index
    error IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS(uint256 index);
  // **************************************

  // **************************************
  // *****            VIEW            *****
  // **************************************
    /// @dev Enumerate valid NFTs
    ///   Throws if `index_` >= {totalSupply()}.
    function tokenByIndex(uint256 index_) external view returns (uint256);
    /// @dev Enumerate NFTs assigned to an owner
    ///   Throws if `index_` >= {balanceOf(owner_)} or if `owner_` is the zero address, representing invalid NFTs.
    function tokenOfOwnerByIndex(address owner_, uint256 index_) external view returns (uint256);
    /// @dev Count NFTs tracked by this contract
    function totalSupply() external view returns (uint256);
  // **************************************
}

// node_modules/@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721Metadata.sol

// import "./IERC721.sol";

/**
* @dev Required interface of an ERC721 compliant contract, optional metadata extension, as defined in the
* https://eips.ethereum.org/EIPS/eip-721[EIP].
*   Note: the ERC-165 identifier for this interface is 0x5b5e139f.
*/
interface IERC721Metadata /* is IERC721 */ {
  // **************************************
  // *****            VIEW            *****
  // **************************************
    /// @dev A descriptive name for a collection of NFTs in this contract
    function name() external view returns (string memory);
    /// @dev An abbreviated name for NFTs in this contract
    function symbol() external view returns (string memory);
    /// @dev A distinct Uniform Resource Identifier (URI) for a given asset.
    ///   Throws if `tokenId_` is not a valid NFT. URIs are defined in RFC 3986.
    ///   The URI may point to a JSON file that conforms to the "ERC721 Metadata JSON Schema".
    function tokenURI(uint256 tokenId_) external view returns (string memory);
  // **************************************
}

// node_modules/@lambdalf-dev/ethereum-contracts/contracts/interfaces/IERC721Receiver.sol

/**
* @dev Required interface of an ERC721 receiver compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-721[EIP].
*   Note: the ERC-165 identifier for this interface is 0x150b7a02.
*/
interface IERC721Receiver {
  // **************************************
  // *****            VIEW            *****
  // **************************************
    /// @dev Handle the receipt of an NFT
    ///   The ERC721 smart contract calls this function on the recipient after a `transfer`.
    ///   This function MAY throw to revert and reject the transfer.
    ///   Return of other than the magic value MUST result in the transaction being reverted.
    ///   Note: the contract address is always the message sender.
    function onERC721Received(
      address operator_,
      address from_,
      uint256 tokenId_,
      bytes calldata data_
    ) external returns(bytes4);
  // **************************************
}

// node_modules/@openzeppelin/contracts/utils/Address.sol

// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// node_modules/@openzeppelin/contracts/proxy/utils/Initializable.sol

// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since 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 Indicates that the contract has been initialized.
     * @custom:oz-retyped-from bool
     */
    uint8 private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint8 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 functions marked with `initializer` can be nested in the context of a
     * constructor.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        bool isTopLevelCall = !_initializing;
        require(
            (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),
            "Initializable: contract is already initialized"
        );
        _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 255 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint8 version) {
        require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
        _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() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    /**
     * @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 {
        require(!_initializing, "Initializable: contract is initializing");
        if (_initialized != type(uint8).max) {
            _initialized = type(uint8).max;
            emit Initialized(type(uint8).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint8) {
        return _initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _initializing;
    }
}

// src/interfaces/IAsset.sol

interface IAsset is IERC721, IERC721Metadata {}

// src/ERC173Initializable.sol

/**
 * Author: Lambdalf the White
 */

abstract contract ERC173Initializable is IERC173, Initializable {
  // **************************************
  // *****     STORAGE VARIABLES      *****
  // **************************************
  /// @dev The current contract owner.
  address private _owner;
  // **************************************

  function _init_ERC173(address owner_) internal onlyInitializing {
    _owner = owner_;
  }

  // **************************************
  // *****          MODIFIERS         *****
  // **************************************
  /// @dev Throws if called by any account other than the owner.
  modifier onlyOwner() {
    if (owner() != msg.sender) {
      revert IERC173_NOT_OWNER(msg.sender);
    }
    _;
  }
  // **************************************

  // **************************************
  // *****       CONTRACT_OWNER       *****
  // **************************************
  /// @dev Transfers ownership of the contract to `newOwner_`.
  ///
  /// @param newOwner_ address of the new contract owner
  ///
  /// Requirements:
  ///
  /// - Caller must be the contract owner.
  function transferOwnership(address newOwner_) public virtual override onlyOwner {
    address _oldOwner_ = _owner;
    _owner = newOwner_;
    emit OwnershipTransferred(_oldOwner_, newOwner_);
  }
  // **************************************

  // **************************************
  // *****            VIEW            *****
  // **************************************
  /// @dev Returns the address of the current contract owner.
  ///
  /// @return contractOwner the current contract owner
  function owner() public view virtual override returns (address contractOwner) {
    return _owner;
  }
  // **************************************
}

// src/ERC2981Initializable.sol

/**
 * Author: Lambdalf the White
 */

abstract contract ERC2981Initializable is IERC2981, Initializable {
  // **************************************
  // *****         DATA TYPES         *****
  // **************************************
  /// @dev A structure representing royalties
  struct RoyaltyData {
    address recipient;
    uint96 rate;
  }
  // **************************************

  // **************************************
  // *****    BYTECODE  VARIABLES     *****
  // **************************************
  /// @dev Royalty rate is stored out of 10,000 instead of a percentage
  ///   to allow for up to two digits below the unit such as 2.5% or 1.25%.
  uint256 public constant ROYALTY_BASE = 10_000;
  // **************************************

  // **************************************
  // *****     STORAGE VARIABLES      *****
  // **************************************
  /// @dev Represents the royalties on each sale on secondary markets.
  ///   Set rate to 0 to have no royalties.
  RoyaltyData private _royaltyData;
  // **************************************

  function _init_ERC2981(address royaltyRecipient_, uint96 royaltyRate_) internal onlyInitializing {
    _setRoyaltyInfo(royaltyRecipient_, royaltyRate_);
  }

  // **************************************
  // *****            VIEW            *****
  // **************************************
  /// @dev Called with the sale price to determine how much royalty is owed and to whom.
  ///
  /// @param tokenId_ identifier of the NFT being referenced
  /// @param salePrice_ the sale price of the token sold
  ///
  /// @return receiver the address receiving the royalties
  /// @return royaltyAmount the royalty payment amount
  /* solhint-disable no-unused-vars */
  function royaltyInfo(
    uint256 tokenId_,
    uint256 salePrice_
  ) public view virtual override returns (address receiver, uint256 royaltyAmount) {
    RoyaltyData memory _data_ = _royaltyData;
    if (salePrice_ == 0 || _data_.rate == 0 || _data_.recipient == address(0)) {
      return (address(0), 0);
    }
    uint256 _royaltyAmount_ = _data_.rate * salePrice_ / ROYALTY_BASE;
    return (_data_.recipient, _royaltyAmount_);
  }
  /* solhint-enable no-unused-vars */
  // **************************************

  // **************************************
  // *****          INTERNAL          *****
  // **************************************
  /// @dev Sets the royalty rate to `newRoyaltyRate_` and the royalty recipient to `newRoyaltyRecipient_`.
  ///
  /// @param newRoyaltyRecipient_ the address that will receive royalty payments
  /// @param newRoyaltyRate_ the percentage of the sale price that will be taken off as royalties,
  ///   expressed in Basis Points (100 BP = 1%)
  ///
  /// Requirements:
  ///
  /// - `newRoyaltyRate_` cannot be higher than {ROYALTY_BASE};
  function _setRoyaltyInfo(address newRoyaltyRecipient_, uint96 newRoyaltyRate_) internal virtual {
    if (newRoyaltyRate_ > ROYALTY_BASE) {
      revert IERC2981_INVALID_ROYALTIES();
    }
    _royaltyData = RoyaltyData(newRoyaltyRecipient_, newRoyaltyRate_);
  }
  // **************************************
}

// src/Wrapped721.sol

/**
 * Author: Lambdalf the White
 */

contract Wrapped721 is IERC165, ERC173Initializable, ERC2981Initializable, IERC721, IERC721Metadata, IERC721Enumerable {
  // **************************************
  // *****           ERRORS           *****
  // **************************************
  /// @dev Thrown when trying to withdraw from the contract with no balance.
  error ETHER_NO_BALANCE();
  /// @dev Thrown when contract fails to send ether to recipient.
  ///
  /// @param to the recipient of the ether
  /// @param amount the amount of ether being sent
  error ETHER_TRANSFER_FAIL(address to, uint256 amount);
  // **************************************

  // **************************************
  // *****     STORAGE VARIABLES      *****
  // **************************************
  IAsset public underlyingAsset;

  // ***********
  // * IERC721 *
  // ***********
  /// @dev Number of NFT tracked by this contract
  uint256 public totalSupply;
  /// @dev Token ID mapped to approved address
  mapping(uint256 => address) private _approvals;
  /// @dev Token owner mapped to operator approvals
  mapping(address => mapping(address => bool)) private _operatorApprovals;
  /// @dev List of owner addresses
  mapping(uint256 => address) private _owners;
  /// @dev List of owner balances
  mapping(address => uint256) private _balances;
  // ***********

  // *******************
  // * IERC721Metadata *
  // *******************
  /// @dev The token's base URI.
  string private _baseUri;
  // *******************
  // **************************************

  constructor() {
    initialize(address(0), address(0), address(0), 0, "");
  }

  function initialize(
    address admin_,
    address asset_,
    address royaltyRecipient_,
    uint96 royaltyRate_,
    string memory baseUri_
  ) public initializer {
    underlyingAsset = IAsset(asset_);
    _setBaseUri(baseUri_);
    _init_ERC173(admin_);
    _init_ERC2981(royaltyRecipient_, royaltyRate_);
  }

  // **************************************
  // *****          FALLBACK          *****
  // **************************************
  fallback() external payable {} // solhint-disable no-empty-blocks
  receive() external payable {} // solhint-disable no-empty-blocks
  // **************************************

  // **************************************
  // *****          MODIFIER          *****
  // **************************************
  // ***********
  // * IERC721 *
  // ***********
  /// @dev Throws if `tokenId_` doesn't exist.
  /// A token exists if it has been minted and is not owned by the zero address.
  ///
  /// @param tokenId_ identifier of the NFT being referenced
  modifier exists(uint256 tokenId_) {
    if (_owners[tokenId_] == address(0)) {
      revert IERC721_NONEXISTANT_TOKEN(tokenId_);
    }
    _;
  }
  // ***********
  // **************************************

  // **************************************
  // *****           PUBLIC           *****
  // **************************************
  /// @dev Wraps a token from the underlying collection and transfers it to `toAddress_`.
  ///
  /// @param tokenIds_ list of identifiers of the NFT being referenced
  ///
  /// Requirements:
  ///
  /// - The token number `tokenId_` must exist in the underlying collection.
  /// - The caller must own the token in the underlying collection.
  /// - This contract must be allowed to transfer `tokenId_` from the underlying collection on behalf of the caller.
  function wrap(uint256[] calldata tokenIds_) public {
    unchecked {
      totalSupply += tokenIds_.length;
      _balances[msg.sender] += tokenIds_.length;
    }
    for (uint256 i; i < tokenIds_.length; ++i) {
      _owners[tokenIds_[i]] = msg.sender;
      emit Transfer(address(0), msg.sender, tokenIds_[i]);
      underlyingAsset.transferFrom(msg.sender, address(this), tokenIds_[i]);
    }
  }
  /// @dev Unwraps a token from the underlying collection and transfers it to `toAddress_`.
  ///
  /// @param tokenIds_ list of identifiers of the NFT being referenced
  ///
  /// Requirements:
  ///
  /// - The token number `tokenId_` must exist in the underlying collection.
  /// - The caller must own the token or be an approved operator.

  function unwrap(uint256[] calldata tokenIds_) public {
    unchecked {
      totalSupply -= tokenIds_.length;
      _balances[msg.sender] -= tokenIds_.length;
    }
    for (uint256 i; i < tokenIds_.length; ++i) {
      if (_owners[tokenIds_[i]] != msg.sender) {
        revert IERC721_CALLER_NOT_APPROVED(msg.sender, tokenIds_[i]);
      }
      _owners[tokenIds_[i]] = address(0);
      emit Transfer(msg.sender, address(0), tokenIds_[i]);
      underlyingAsset.transferFrom(address(this), msg.sender, tokenIds_[i]);
    }
  }
  // ***********
  // * IERC721 *
  // ***********
  /// @dev Gives permission to `to_` to transfer the token number `tokenId_` on behalf of its owner.
  /// 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.
  ///
  /// @param to_ The new approved NFT controller
  /// @param tokenId_ The NFT to approve
  ///
  /// Requirements:
  ///
  /// - The token number `tokenId_` must exist.
  /// - The caller must own the token or be an approved operator.
  /// - Must emit an {Approval} event.

  function approve(address to_, uint256 tokenId_) public virtual override {
    address _tokenOwner_ = ownerOf(tokenId_);
    if (to_ == _tokenOwner_) {
      revert IERC721_INVALID_APPROVAL();
    }
    bool _isApproved_ = _isApprovedOrOwner(_tokenOwner_, msg.sender, tokenId_);
    if (!_isApproved_) {
      revert IERC721_CALLER_NOT_APPROVED(msg.sender, tokenId_);
    }
    _approvals[tokenId_] = to_;
    emit Approval(_tokenOwner_, to_, tokenId_);
  }
  /// @dev Transfers the token number `tokenId_` from `from_` to `to_`.
  ///
  /// @param from_ The current owner of the NFT
  /// @param to_ The new owner
  /// @param tokenId_ identifier of the NFT being referenced
  ///
  /// Requirements:
  ///
  /// - The token number `tokenId_` must exist.
  /// - `from_` must be the token owner.
  /// - The caller must own the token or be an approved operator.
  /// - `to_` must not be the zero address.
  /// - If `to_` is a contract, it must implement {IERC721Receiver-onERC721Received} with a return value of `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`,
  /// - Must emit a {Transfer} event.

  function safeTransferFrom(address from_, address to_, uint256 tokenId_) public virtual override {
    safeTransferFrom(from_, to_, tokenId_, "");
  }
  /// @dev Transfers the token number `tokenId_` from `from_` to `to_`.
  ///
  /// @param from_ The current owner of the NFT
  /// @param to_ The new owner
  /// @param tokenId_ identifier of the NFT being referenced
  /// @param data_ Additional data with no specified format, sent in call to `to_`
  ///
  /// Requirements:
  ///
  /// - The token number `tokenId_` must exist.
  /// - `from_` must be the token owner.
  /// - The caller must own the token or be an approved operator.
  /// - `to_` must not be the zero address.
  /// - If `to_` is a contract, it must implement {IERC721Receiver-onERC721Received} with a return value of `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`,
  /// - Must emit a {Transfer} event.

  function safeTransferFrom(address from_, address to_, uint256 tokenId_, bytes memory data_) public virtual override {
    transferFrom(from_, to_, tokenId_);
    if (!_checkOnERC721Received(from_, to_, tokenId_, data_)) {
      revert IERC721_INVALID_RECEIVER(to_);
    }
  }
  /// @dev Allows or disallows `operator_` to manage the caller's tokens on their behalf.
  ///
  /// @param operator_ Address to add to the set of authorized operators
  /// @param approved_ True if the operator is approved, false to revoke approval
  ///
  /// Requirements:
  ///
  /// - Must emit an {ApprovalForAll} event.

  function setApprovalForAll(address operator_, bool approved_) public virtual override {
    if (operator_ == msg.sender) {
      revert IERC721_INVALID_APPROVAL();
    }
    _operatorApprovals[msg.sender][operator_] = approved_;
    emit ApprovalForAll(msg.sender, operator_, approved_);
  }
  /// @dev Transfers the token number `tokenId_` from `from_` to `to_`.
  ///
  /// @param from_ the current owner of the NFT
  /// @param to_ the new owner
  /// @param tokenId_ identifier of the NFT being referenced
  ///
  /// Requirements:
  ///
  /// - The token number `tokenId_` must exist.
  /// - `from_` must be the token owner.
  /// - The caller must own the token or be an approved operator.
  /// - `to_` must not be the zero address.
  /// - Must emit a {Transfer} event.

  function transferFrom(address from_, address to_, uint256 tokenId_) public virtual override {
    if (to_ == address(0)) {
      revert IERC721_INVALID_RECEIVER(to_);
    }
    address _tokenOwner_ = ownerOf(tokenId_);
    if (from_ != _tokenOwner_) {
      revert IERC721_INVALID_TOKEN_OWNER();
    }
    if (!_isApprovedOrOwner(_tokenOwner_, msg.sender, tokenId_)) {
      revert IERC721_CALLER_NOT_APPROVED(msg.sender, tokenId_);
    }
    unchecked {
      --_balances[from_];
      ++_balances[to_];
    }
    _transfer(from_, to_, tokenId_);
  }
  // ***********
  // ***********************
  // * ERC721BatchBurnable *
  // ***********************
  /// @dev Burns `tokenId_`.
  ///
  /// Requirements:
  ///
  /// - `tokenId_` must exist
  /// - The caller must own `tokenId_` or be an approved operator

  function burn(uint256 tokenId_) public {
    address _tokenOwner_ = ownerOf(tokenId_);
    if (!_isApprovedOrOwner(_tokenOwner_, msg.sender, tokenId_)) {
      revert IERC721_CALLER_NOT_APPROVED(msg.sender, tokenId_);
    }
    unchecked {
      --totalSupply;
      --_balances[msg.sender];
    }
    _transfer(_tokenOwner_, address(0), tokenId_);
  }
  // ***********************
  // **************************************

  // **************************************
  // *****       CONTRACT_OWNER       *****
  // **************************************
  /// @notice Withdraws all the money stored in the contract and sends it to the treasury.
  ///
  /// Requirements:
  ///
  /// - Caller must be the contract owner.
  /// - Contract must have a positive balance.
  /// - Caller must be able to receive the funds.
  function withdraw() public onlyOwner {
    uint256 _balance_ = address(this).balance;
    if (_balance_ == 0) {
      revert ETHER_NO_BALANCE();
    }

    // solhint-disable-next-line
    (bool _success_,) = payable(msg.sender).call{value: _balance_}("");
    if (!_success_) {
      revert ETHER_TRANSFER_FAIL(msg.sender, _balance_);
    }
  }

  // *******************
  // * IERC721Metadata *
  // *******************
  /// @notice Updates the baseUri for the tokens.
  ///
  /// @param newBaseUri_ the new baseUri for the tokens
  ///
  /// Requirements:
  ///
  /// - Caller must be the contract owner.
  function setBaseUri(string memory newBaseUri_) public onlyOwner {
    _setBaseUri(newBaseUri_);
  }
  // *******************

  // ************
  // * IERC2981 *
  // ************
  /// @dev Sets the royalty rate to `newRoyaltyRate_` and the royalty recipient to `newRoyaltyRecipient_`.
  ///
  /// @param newRoyaltyRecipient_ the address that will receive royalty payments
  /// @param newRoyaltyRate_ the percentage of the sale price that will be taken off as royalties,
  ///   expressed in Basis Points (100 BP = 1%)
  ///
  /// Requirements:
  ///
  /// - Caller must be the contract owner.
  /// - `newRoyaltyRate_` cannot be higher than {ROYALTY_BASE};
  function setRoyaltyInfo(address newRoyaltyRecipient_, uint96 newRoyaltyRate_) public onlyOwner {
    _setRoyaltyInfo(newRoyaltyRecipient_, newRoyaltyRate_);
  }
  // ************
  // **************************************

  // **************************************
  // *****            VIEW            *****
  // **************************************
  // ***********
  // * IERC721 *
  // ***********
  /// @dev Returns the number of tokens in `tokenOwner_`'s account.
  ///
  /// @param tokenOwner_ address that owns tokens
  ///
  /// @return ownerBalance the nomber of tokens owned by `tokenOwner_`
  ///
  /// Requirements:
  ///
  /// - `tokenOwner_` must not be the zero address
  function balanceOf(address tokenOwner_) public view virtual override returns (uint256 ownerBalance) {
    if (tokenOwner_ == address(0)) {
      revert IERC721_INVALID_TOKEN_OWNER();
    }
    ownerBalance = _balances[tokenOwner_];
  }
  /// @dev Returns the address that has been specifically allowed to manage `tokenId_` on behalf of its owner.
  ///
  /// @param tokenId_ the NFT that has been approved
  ///
  /// @return approved the address allowed to manage `tokenId_`
  ///
  /// Requirements:
  ///
  /// - `tokenId_` must exist.
  ///
  /// Note: See {Approve}

  function getApproved(uint256 tokenId_) public view virtual override returns (address approved) {
    if (_owners[tokenId_] == address(0)) {
      revert IERC721_NONEXISTANT_TOKEN(tokenId_);
    }
    return _approvals[tokenId_];
  }
  /// @dev Returns whether `operator_` is allowed to manage tokens on behalf of `tokenOwner_`.
  ///
  /// @param tokenOwner_ address that owns tokens
  /// @param operator_ address that tries to manage tokens
  ///
  /// @return isApproved whether `operator_` is allowed to handle `tokenOwner`'s tokens
  ///
  /// Note: See {setApprovalForAll}

  function isApprovedForAll(
    address tokenOwner_,
    address operator_
  ) public view virtual override returns (bool isApproved) {
    return _operatorApprovals[tokenOwner_][operator_];
  }
  /// @dev Returns the owner of the token number `tokenId_`.
  ///
  /// @param tokenId_ the NFT to verify ownership of
  ///
  /// @return tokenOwner the owner of token number `tokenId_`
  ///
  /// Requirements:
  ///
  /// - `tokenId_` must exist.

  function ownerOf(uint256 tokenId_) public view virtual override returns (address tokenOwner) {
    tokenOwner = _owners[tokenId_];
    if (tokenOwner == address(0)) {
      revert IERC721_NONEXISTANT_TOKEN(tokenId_);
    }
  }
  // ***********

  // *********************
  // * IERC721Enumerable *
  // *********************
  /// @dev Enumerate valid NFTs
  ///
  /// @param index_ the index requested
  ///
  /// @return tokenId the identifier of the token at the specified index
  ///
  /// Requirements:
  ///
  /// - `index_` must be less than {totalSupply}
  function tokenByIndex(uint256 index_) public view virtual override returns (uint256) {
    if (index_ >= totalSupply) {
      revert IERC721Enumerable_INDEX_OUT_OF_BOUNDS(index_);
    }

    uint256 _count_;
    uint256 _id_;
    while (_count_ <= index_) {
      if (_owners[_id_] != address(0)) {
        if (index_ == _count_) {
          return _id_;
        }
        unchecked {
          ++_count_;
        }
      }
      unchecked {
        ++_id_;
      }
    }
  }
  /// @dev Enumerate NFTs assigned to an owner
  ///
  /// @param tokenOwner_ the address requested
  /// @param index_ the index requested
  ///
  /// @return tokenId the identifier of the token at the specified index
  ///
  /// Requirements:
  ///
  /// - `index_` must be less than {balanceOf(tokenOwner_)}
  /// - `tokenOwner_` must not be the zero address

  function tokenOfOwnerByIndex(address tokenOwner_, uint256 index_) public view virtual override returns (uint256) {
    if (tokenOwner_ == address(0)) {
      revert IERC721_INVALID_TOKEN_OWNER();
    }
    if (index_ >= _balances[tokenOwner_]) {
      revert IERC721Enumerable_OWNER_INDEX_OUT_OF_BOUNDS(index_);
    }

    uint256 _count_;
    uint256 _id_;
    while (_count_ <= index_) {
      if (_owners[_id_] == tokenOwner_) {
        if (index_ == _count_) {
          return _id_;
        }
        unchecked {
          ++_count_;
        }
      }
      unchecked {
        ++_id_;
      }
    }
  }
  // *********************

  // *******************
  // * IERC721Metadata *
  // *******************
  /// @dev A descriptive name for a collection of NFTs in this contract
  ///
  /// @return tokenName The descriptive name of the NFTs
  function name() public view virtual override returns (string memory tokenName) {
    tokenName = underlyingAsset.name();
  }
  /// @dev An abbreviated name for NFTs in this contract
  ///
  /// @return tokenSymbol The abbreviated name of the NFTs

  function symbol() public view virtual override returns (string memory tokenSymbol) {
    tokenSymbol = underlyingAsset.symbol();
  }
  /// @dev A distinct Uniform Resource Identifier (URI) for a given asset.
  ///
  /// @param tokenId_ the NFT that has been approved
  ///
  /// @return uri the URI of the token
  ///
  /// Requirements:
  ///
  /// - `tokenId_` must exist.

  function tokenURI(uint256 tokenId_) public view virtual override returns (string memory uri) {
    if (_owners[tokenId_] == address(0)) {
      revert IERC721_NONEXISTANT_TOKEN(tokenId_);
    }
    return bytes(_baseUri).length > 0 ? string(abi.encodePacked(_baseUri, _toString(tokenId_))) : _toString(tokenId_);
  }
  // *******************

  // ***********
  // * IERC165 *
  // ***********
  /// @dev Query if a contract implements an interface.
  /// @dev see https://eips.ethereum.org/EIPS/eip-165
  ///
  /// @param interfaceId_ the interface identifier, as specified in ERC-165
  ///
  /// @return bool true if the contract implements the specified interface, false otherwise
  ///
  /// Requirements:
  ///
  /// - This function must use less than 30,000 gas.
  function supportsInterface(bytes4 interfaceId_) public pure override returns (bool) {
    return interfaceId_ == type(IERC721).interfaceId || interfaceId_ == type(IERC721Enumerable).interfaceId
      || interfaceId_ == type(IERC721Metadata).interfaceId || interfaceId_ == type(IERC173).interfaceId
      || interfaceId_ == type(IERC165).interfaceId || interfaceId_ == type(IERC2981).interfaceId;
  }
  // ***********
  // **************************************

  // **************************************
  // *****          INTERNAL          *****
  // **************************************
  // ***********
  // * IERC721 *
  // ***********
  /// @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
  /// The call is not executed if the target address is not a contract.
  ///
  /// @param from_ address owning the token being transferred
  /// @param to_ address the token is being transferred to
  /// @param tokenId_ identifier of the NFT being referenced
  /// @param data_ optional data to send along with the call
  ///
  /// @return isValidReceiver whether the call correctly returned the expected value
  function _checkOnERC721Received(
    address from_,
    address to_,
    uint256 tokenId_,
    bytes memory data_
  ) internal virtual returns (bool isValidReceiver) {
    // This method relies on extcodesize, which returns 0 for contracts in
    // construction, since the code is only stored at the end of the
    // constructor execution.
    //
    // IMPORTANT
    // It is unsafe to assume that an address not flagged by this method
    // is an externally-owned account (EOA) and not a contract.
    //
    // Among others, the following types of addresses will not be flagged:
    //
    //  - an externally-owned account
    //  - a contract in construction
    //  - an address where a contract will be created
    //  - an address where a contract lived, but was destroyed
    uint256 _size_;
    assembly {
      _size_ := extcodesize(to_)
    }
    // If address is a contract, check that it is aware of how to handle ERC721 tokens
    if (_size_ > 0) {
      try IERC721Receiver(to_).onERC721Received(msg.sender, from_, tokenId_, data_) returns (bytes4 retval) {
        return retval == IERC721Receiver.onERC721Received.selector;
      } catch (bytes memory reason) {
        if (reason.length == 0) {
          revert IERC721_INVALID_RECEIVER(to_);
        } else {
          assembly {
            revert(add(32, reason), mload(reason))
          }
        }
      }
    } else {
      return true;
    }
  }
  /// @dev Internal function returning whether `operator_` is allowed to handle `tokenId_`
  ///
  /// Note: To avoid multiple checks for the same data, it is assumed
  /// that existence of `tokenId_` has been verified prior via {_exists}
  /// If it hasn't been verified, this function might panic
  ///
  /// @param operator_ address that tries to handle the token
  /// @param tokenId_ identifier of the NFT being referenced
  ///
  /// @return isApproved whether `operator_` is allowed to manage the token

  function _isApprovedOrOwner(
    address tokenOwner_,
    address operator_,
    uint256 tokenId_
  ) internal view virtual returns (bool isApproved) {
    return operator_ == tokenOwner_ || operator_ == getApproved(tokenId_) || _operatorApprovals[tokenOwner_][operator_];
  }
  /// @dev Transfers `tokenId_` from `fromAddress_` to `toAddress_`.
  ///
  /// Emits a {Transfer} event.
  ///
  /// @param fromAddress_ the current owner of the NFT
  /// @param toAddress_ the new owner
  /// @param tokenId_ identifier of the NFT being referenced

  function _transfer(address fromAddress_, address toAddress_, uint256 tokenId_) internal virtual {
    _approvals[tokenId_] = address(0);
    _owners[tokenId_] = toAddress_;
    emit Transfer(fromAddress_, toAddress_, tokenId_);
  }
  // ***********

  // *******************
  // * IERC721Metadata *
  // *******************
  /// @notice Updates the baseUri for the tokens.
  ///
  /// @param newBaseUri_ the new baseUri for the tokens
  ///
  /// Requirements:
  ///
  /// - Caller must be the contract owner.
  function _setBaseUri(string memory newBaseUri_) internal virtual {
    _baseUri = newBaseUri_;
  }
  /// @dev Converts a `uint256` to its ASCII `string` decimal representation.
  ///
  /// @param value_ the value to convert to string.
  ///
  /// @return str the string representation of `value_`

  function _toString(uint256 value_) internal pure virtual returns (string memory str) {
    assembly {
      // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
      // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
      // We will need 1 word for the trailing zeros padding, 1 word for the length,
      // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
      let m := add(mload(0x40), 0xa0)
      // Update the free memory pointer to allocate.
      mstore(0x40, m)
      // Assign the `str` to the end.
      str := sub(m, 0x20)
      // Zeroize the slot after the string.
      mstore(str, 0)

      // Cache the end of the memory to calculate the length later.
      let end := str

      // We write the string from rightmost digit to leftmost digit.
      // The following is essentially a do-while loop that also handles the zero case.
      // prettier-ignore
      for { let temp := value_ } 1 {} {
        // solhint-disable-line
        str := sub(str, 1)
        // Write the character to the pointer.
        // The ASCII index of the '0' character is 48.
        mstore8(str, add(48, mod(temp, 10)))
        // Keep dividing `temp` until zero.
        temp := div(temp, 10)
        // prettier-ignore
        if iszero(temp) { break }
      }

      let length := sub(end, str)
      // Move the pointer 32 bytes leftwards to make room for the length.
      str := sub(str, 0x20)
      // Store the length.
      mstore(str, length)
    }
  }
  // *******************
  // **************************************
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):