As of 23 Oct 2026, Ommniverse has 1 audit report on Trustblock, by CertiK, dated 5 Mar 2023. That report lists no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Ommniverse | Security firm: CertiK | Date: | Scope: Files named in the report | No open critical findings | Original removed |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 4 |
| Medium | 2 | 0 | 8 |
| Low | 0 | 0 | 13 |
In the contract **Governance**, the role **Owner** has authority over the following functions: - function createProposal(), to create a proposal. - function executeProposal(), to execute a proposal. Any compromise to the **Owner** account may allow a hacker to take advantage of this authority. In the contract **Fractions**, the role **Owner** has authority over the following functions: - function addMinter(), to add the address `minter` as the `Minter` role. - function removeMinter(), to remove the address `minter` from the `Minter` role. - function updateBaseUri(), to update the base URI of the fractions. Any compromise to the **Owner** account may allow a hacker to take advantage of this authority. In the contract **Fractions**, the role **Minter** has authority over the following functions: - function mint(), to mint any amount of fractions to any address. Any compromise to the **Minter** account may allow a hacker to take advantage of this authority. In the contract **NftVaultFactory**, the role **Owner** has authority over the following functions: - function setFeeReceiver(), to update the fee receiver. - function setFee(), to update the fee. Any compromise to the **Owner** account may allow a hacker to take advantage of this authority. In the contract **Ommniverse**, the role **Owner** has authority over the following functions: - function pause(), to return the contract to a normal state. - function unpause(), to trigger a stopped state. - function mint(), to mint `OMMI` ERC20 tokens to any address. Any compromise to the **Owner** account may allow a hacker to take advantage of this authority. In the contract **VaultFactory**, the role **Owner** has authority over the following functions: - function setFeeReceiver(), set update the fee receiver. - function setFee(), to update the fee. - setAuctionLength(), to update the auction length. Any compromise to the **Owner** account may allow a hacker to take advantage of this authority.
Open the report`Fractions`,`NftVault`, `NftVaultFactory`,`OmmniverseCollection`,`Ommniverse`,`Vault`, and `VaultFactory` are upgradeable contracts, the owner can upgrade the contract without the community's commitment. If an attacker compromises the account, he can change the implementation of the contract and drain tokens from the contract.
Open the reportAll calls of the form `transferFrom(from, dest, amount)` where the `dest` address is zero will fail. ```solidity OmmniToken.transferFrom(msg.sender, address(0), burn) ```
Open the reportThe `vote()` function allows token holders to vote on proposals, and the number of votes cast depends on the user's total quantity of voting tokens. Although each user can only vote once, the voting tokens are not locked, allowing the holder of the voting tokens freely transfer the voting tokens to any address after casting the vote, giving that address more voting power and potentially manipulating the voting outcome. ```solidity=108 function vote(uint256 _proposalId, bool _vote) public { require(proposals[_proposalId].votingPeriod > block.timestamp); require(!voters[_proposalId][msg.sender], "Already voted"); if (_vote) { voteTotals[_proposalId].yes += token.balanceOf(msg.sender); } else { voteTotals[_proposalId].no += token.balanceOf(msg.sender); } voters[_proposalId][msg.sender] = true; emit VoteCast(_proposalId, msg.sender, _vote); } ```
Open the reportIn the function `end`, the fee sent to the fee receiver is not correctly calculated, there is a duplicated `liveprice` multiplied in the calculation formula. ```solidity _sendOmmi( ISettings(settings).feeReceiver(), livePrice * livePrice * ((ISettings(settings).fee()) / 1000) ); ```
Open the reportThe variable `address(this).balance` is being used to calculate the share of the `Ommni` token is incorrect. `address(this).balance` represents the balance of ETH in the contract `Vault`, it should use the balance of the `Ommni` token. ```solidity=204 fractionValue = address(this).balance / IFERC1155(fractions).totalSupply(fractionsID); ``` ```solidity=215 uint256 share = bal * fractionValue; IFERC1155(fractions).burn(msg.sender, fractionsID, bal); _sendOmmni(msg.sender, share); ```
Open the reportThe parameter `address(this)` passed in function `IFERC1155(fractions).mint()` is incorrect, the parameter should be the address of the vault. ```solidity=89 uint256 fractionId = IFERC1155(fractions).mint(address(this), _amount); ``` ```solidity=46 function mint( address vault, uint256 amount ) external onlyMinter returns (uint256) { count++; idToVault[count] = vault; _mint(msg.sender, count, amount, "0"); _totalSupply[count] = amount; return count; } ```
Open the reportAs per the code comments of the `start()` function, `reservePrice` in `OMMI` must be sent to the contract from the caller. Hence there should be a validation of the amount to ensure that the starting auction price is not smaller than the reserve price.
Open the reportIn the `buyFraction()` function, there should be a validation to ensure that users can only buy NFT fractions before the NFT auction starts.
Open the reportThere is no validation that an existing vesting schedule was created for the beneficiary, so the previous vesting schedule of the beneficiary will be overwritten. ```solidity=37 mapping(address => VestingSchedule) vestingSchedules; ``` ```solidity=88 vestingSchedules[_beneficiary] = VestingSchedule( _beneficiary, _start, cliff, _duration, _slicePeriodSeconds, _amount, 0 ); ```
Open the reportThe functions that are declared `payable` can receive ether. As per the description in the code comments, the functions `buyFraction()`, `start()`, and `bid()` are not designed for receiving ether, so they are redundant to have the `payable` modifier. ```solidity=108 /// @notice buys fractions of the Nft. Must send price in Ommni function buyFraction(uint256 _amount) external payable nonReentrant { ``` ```solidity=154 /// @notice kick off an auction. Must send reservePrice in Ommni function start(uint256 _amount) external payable nonReentrant { ```
Open the reportIn the function `start()`, there is no validation to ensure that the auction does not start before fractions of the NFT are sold out.
Open the reportIn the function `_computeReleasableAmount`, the release amount is calculated from the cliff time instead of the start time. We would like to confirm with the client if the current implementation aligns with the original project design.
Open the reportThe variables do not have reasonable boundaries, so they can be given arbitrary values after deploying.
Open the reportFunctions that affect the status of sensitive variables should be able to emit events as notifications to customers.
Open the reportAddresses should be checked before assignment or external call to make sure they are not zero addresses. ```solidity=84 fractions = _fractions; ``` - `_fractions` is not zero-checked before being used. --- ```solidity=86 underlying = _underlying; ``` - `_underlying` is not zero-checked before being used. --- ```solidity=88 curator = _curator; ``` - `_curator` is not zero-checked before being used. --- ```solidity=34 fnft = _fnft; ``` - `_fnft` is not zero-checked before being used. --- ```solidity=35 ommni = _ommni; ``` - `_ommni` is not zero-checked before being used. --- ```solidity=69 feeReceiver = _feeReceiver; ``` - `_feeReceiver` is not zero-checked before being used.
Open the reportThe cited address input is missing a check that it is not `address(0)`.
Open the reportUsers can buy ERC721 tokens in the `NftVault` contract using `OMMI` tokens, which are sent to the fee receiver. However, no `OMMI` tokens are sent to the ERC721 token's owner. Similarly, In the `Vault` contract, if the ERC721 token is successfully auctioned off, all `OMMI` tokens will be possibly distributed by the fractions owners, and there is no withdrawal function for the vault owner to retrieve the `OMMI` tokens in the contract. We would like to confirm with the client that the current implementation aligns with the original project design.
Open the reportBecause there is no validation to guarantee the name and symbol are unique, anybody may use the function `mintContact()` to establish the `UserCllection` contract with the same name and symbol.
Open the reportThe aforementioned lines cast the contract to the payable address yet no ether transfer is performed. ```solidity=154 address payable beneficiaryPayable = payable( vestingSchedule.beneficiary ); ```
Open the reportSolidity version >=0.8.0 includes checked arithmetic operations and underflow/overflow by default, making SafeMath redundant.
Open the reportWhen the supply of `OMMI` tokens reaches half of the total supply, half of the `OMMI` tokens paid for buying NFT/ERC1155 will be burned. We failed to find any design documentation for this part of the business logic. ```solidity=84 if (OmmniToken.totalSupply() <= 3000000 * 10 * 18) { uint256 burn = nftPrice / 2; require( OmmniToken.transferFrom( msg.sender, ISettings(settings).feeReceiver(), burn ) && OmmniToken.transferFrom(msg.sender, address(0), burn), "Ommni Transfer failed" ); } ``` ```solidity=125 if (OmmniToken.totalSupply() <= 3000000 * 10 * 18) { uint256 burn = (_amount * omni_price) / 2; require( OmmniToken.transferFrom(msg.sender, address(this), burn) && OmmniToken.transferFrom(msg.sender, address(0), burn), "Ommni Transfer failed" ); } ``` We would like the team to elaborate more about the purpose of burning tokens and the intention of the condition: ```solidity OmmniToken.totalSupply() <= 3000000 * 10 * 18 ```
Open the reportThe return value of the transfer()/transferFrom() call is not checked. ```solidity=141 OmmniToken.transferFrom(msg.sender, address(this), _amount); ``` --- ```solidity=158 OmmniToken.transferFrom(msg.sender, address(this), _amount); ``` --- ```solidity=197 OmmniToken.transfer(_to, _value); ```
Open the reportThe payable receive() and fallback() functions allow ethers to be transferred to the contract by mistake, and there is no way to get ethers out of the contract, so those ethers are locked in the contract and lost forever.
Open the reportOne or more logic contracts do not protect their initializers. An attacker can call the initializer and assume ownership of the logic contract, whereby she can perform privileged operations that trick unsuspecting users into believing that she is the owner of the upgradeable contract. ```solidity=9 contract Fractions is Initializable, ERC1155Upgradeable, OwnableUpgradeable { ``` - `Fractions` is an upgradeable contract that does not protect its initializer. ```solidity=20 function initialize() public initializer { ``` - `initialize` is an unprotected initializer function. --- ```solidity=15 contract NftVault is ``` - `NftVault` is an upgradeable contract that does not protect its initializer. ```solidity=44 function initialize( ``` - `initialize` is an unprotected initializer function. --- ```solidity=11 contract NftVaultFactory is Initializable, OwnableUpgradeable { ``` - `NftVaultFactory` is an upgradeable contract that does not protect its initializer. ```solidity=38 function initialize( ``` - `initialize` is an unprotected initializer function. --- ```solidity=11 contract OmmniverseCollection is ``` - `OmmniverseCollection` is an upgradeable contract that does not protect its initializer. ```solidity=24 function initialize() public initializer { ``` - `initialize` is an unprotected initializer function. --- ```solidity=16 contract Vault is ``` - `Vault` is an upgradeable contract that does not protect its initializer. ```solidity=71 function initialize( ``` - `initialize` is an unprotected initializer function. --- ```solidity=11 contract VaultFactory is ``` - `VaultFactory` is an upgradeable contract that does not protect its initializer. ```solidity=49 function initialize( ``` - `initialize` is an unprotected initializer function.
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="ommniverse"></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