As of 14 Oct 2026, OpenSea has 2 audit reports by 1 security firm on Trustblock; the latest is by Quantstamp, dated 2 Sep 2022. Those reports list no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Statuses are the security firms’ own. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| NFT Market (PresetHTC, Auction, Store) | Security firm: Quantstamp | Date: | Scope: Files named in the report | No open critical findings | Open · certificate.quantstamp.com |
| NFTMarket | Security firm: Quantstamp | Date: | Scope: Files named in the report | No open critical findings | Open · certificate.quantstamp.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 1 | 2 | 2 |
| Medium | 0 | 4 | 2 |
| Low | 3 | 8 | 6 |
To confirm basic functionality as well as all corner cases it is advised to have a compilable and passing test suite, ideally covering all lines and branches of the code at least once. The provided contracts came without build scripts and without tests, allowing for basic functionality to be broken unnoticed or introduce bugs.
Open the reportIt is important to validate inputs, even if they only come from trusted addresses, to avoid human error. The following functions do not have a proper validation of input parameters: 1. `NFTAuction.__NFTAuction_init()` does not check that parameter `_storeAddress` is different from `address(0)`. 1. `NFTAuction.__NFTAuction_init()` does not check that parameter `_storeProfit` is smaller than `BASE_PERCENT` (i.e. by calling `checkProfit()` on it). (**Update:** Fixed) 1. `NFTAuction.launchAuction()` does not check that parameter `_contractAddr` is different from `address(0)`. 1. `NFTAuction.launchAuction()` does not check that parameter `tokenID` has not yet been minted. 1. `NFTAuction.launchAuction()` does not check that parameter `_shareProfit` contains different and non-zero addresses. 1. `NFTAuction.batchLaunchAuctions()` does not check that parameter `_contractAddr` is different from `address(0)`. 1. `NFTAuction.batchLaunchAuctions()` does not check that parameter `tokenIds` have not yet been minted. 1. `NFTAuction.batchLaunchAuctions()` does not check that parameter `_shareProfit` contains different and non-zero addresses. 1. `NFTAuction.setAuctionData()` does not check that parameter `_storeAddress` is different from `address(0)`. 1. `NFTAuction.setAuctionLocked()` does not check that the given auction has not already been finalized or cancelled. (**Update:** Fixed) 1. `ERC721PresetHTC.grantMinterRole()` does not check that parameter `account` is different from `address(0)`. 1. `NFTStore.__NFTMarket_init()` does not check that parameter `_storeAddress` is different from `address(0)`. 1. `NFTStore.__NFTAuction_init()` does not check that parameter `_storeProfit` is smaller than `BASE_PERCENT` (i.e. by calling `checkProfit()` on it). (**Update:** Fixed) 1. `NFTStore.launchProduct()` does not check that parameter `_contractAddr` is different from `address(0)`. 1. `NFTStore.launchProduct()` does not check that parameter `_Price` is non-zero. (**Update:** Fixed) 1. `NFTStore.launchProduct()` does not check that parameter `_totalSupply` is non-zero. (**Update:** Fixed) 1. `NFTStore.launchProduct()` does not check that parameter `_shareProfit` contains different and non-zero addresses. 1. `NFTStore.launchProduct()` does not check that parameter `_productTokenIds` contains different token IDs, which are also not yet minted. 1. `NFTStore.setProductLocked()` does not check that the product has not already been sold out or cancelled. (**Update:** Fixed) 1. `NFTStore.setStoreData()` does not check that parameter `_storeAddress` is different from `address(0)`. 1. `merkleProof` in `vipBid()` function and `_merkleRoot` in `setMerkleRoot()` function of both `NFTAuction.sol` and `NFTStore.sol` contracts should not be empty `bytes32`.
Open the reportCertain contracts have state variables, e.g. `owner`, which provide certain addresses with privileged roles. Such roles may pose a risk to end-users. The `NFTAuction.sol` contract contains the following privileged roles: - `DEFAULT_ADMIN_ROLE`, as initialized during the `__NFTAuction_init()` call: - Renounce the role and thereby disable all followingly listed actions, by calling `renounceRole()`. - Add/remove addresses from arbitrary roles and define role admins, by calling `grantRole()`, `revokeRole()` and `_setRoleAdmin()`. - `CONFIGURATOR_ROLE`, as initialized during the `__NFTAuction_init()` call: - Renounce the role and thereby disable all followingly listed actions, by calling `renounceRole()`. - Modify critical contract variables (`storeAddress`, `storeDefaultProfit`, `extraAuctionMinutes`, `priceThreshold` and `priceLimit`), by calling `setAuctionData()` and `setPriceLimit()`. - `LAUNCH_ROLE`, as initialized during the `__NFTAuction_init()` call: - Renounce the role and thereby disable all followingly listed actions, by calling `renounceRole()`. - Launch auctions, by calling `launchAuction()` or `batchLaunchAuctions()`. - Finalize/Terminate finished auctions, by calling `finalizeAuction()`. - Cancle it's own listed auctions, by calling `cancelAuction()`. - Define 'VIP' members for its listed auctions, by calling `setMerkleRoot()`. - Lock/Unlock it's own auctions for 'VIPs' only, by calling `setAuctionLocked()`. The `NFTStore.sol` contract contains the following privileged roles: - `DEFAULT_ADMIN_ROLE`, as initialized during the `__NFTMarket_init()` call: - Renounce the role and thereby disable all followingly listed actions, by calling `renounceRole()`. - Add/remove addresses from arbitrary roles and define role admins, by calling `grantRole()`, `revokeRole()` and `_setRoleAdmin()`. - `CONFIGURATOR_ROLE`, as initialized during the `__NFTMarket_init()` call: - Renounce the role and thereby disable all followingly listed actions, by calling `renounceRole()`. - Modify critical contract variables (`storeAddress` and `storeDefaultProfit`), by calling `setStoreData()`. - `LAUNCH_ROLE`, as initialized during the `__NFTMarket_init()` call: - Renounce the role and thereby disable all followingly listed actions, by calling `renounceRole()`. - Launch NFT sells, by calling `launchProduct()`. - Cancle it's own listings, by calling `cancelProduct()`. - Define 'VIP' members for its listed auctions, by calling `setMerkleRoot()`. - Lock/Unlock it's own auctions for 'VIPs' only, by calling `setProductLocked()`. The `ERC721PresetHTC.sol` contract contains the following privileged roles: - `owner`, as initialized during the `constructor()` call: - Renounce the role and thereby disable all followingly listed actions, by calling `renounceOwnership()`. - Transfer the role to an arbitrary other address, by calling `transferOwnership()`. - Modify the contract URI (`contractUri`), by calling `setContractUri()`. - Modify the base URI (`_baseTokenURI`), by calling `setBaseUri()`. - Modify token URIs (`_tokenURIs[]`), by calling `setTokenURI()`. - Add/Remove arbitrary addressess as minters, by calling `grantMinterRole()`/`revokeMinterRole()`. - `minters[]`, as set via `grantMinterRole()` and checked via `hasMinterRole()`: - Mint new tokens to arbitrary addresses, by calling `mint()`.
Open the reportProjects may rely on block timestamps for various purposes. However, it's important to realize that miners individually set the timestamp of a block, and attackers may be able to manipulate timestamps up to around 15 seconds for their own purposes. If a smart contract relies on a timestamp, it must be taken into account.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="opensea"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us