OmniFusion - Smart Contract Audit Report
Summary
The Omnimorphs team is expanding the functionality of their Omnimorphs NFTs by allowing users to select features of their Omnimorphs and "fuse" them together to combine their traits.
For this audit, we reviewed the OmniFusion Contract at commit 2f3f9a18af446f8dba66d4be1781de58abe3f0c6 on the team's GitHub.
We previously reviewed the project's Omnimorphs NFT Contract here.
Notes on the Contract:Audit Findings Summary
- Any user is able to fuse any two Omnimorphs NFTs they own at any time, as long as fusion is enabled.
- One Omnimorph NFT will remain with the combined traits, the other will be burned in the fusion process.
- A fusion transaction uses input data in the form of a signed message from the off-chain backend of the platform. This message is then decoded into the necessary information for the fusion by the Contract.
- To fuse two Omnimorphs, at least one Catalyst NFT is required. The Catalyst NFTs are burned during the fusion.
- Each Catalyst corresponds to one trait being used in the fusion; a maximum of 6 Catalysts may be used during a single fusion corresponding to a maximum of 6 traits.
- Once an Omnimorph has been fused, it cannot be fused again; a record of the fusion is stored in the Contract.
- Users will receive a SoulShard NFT that represents the Omnimorph intended to be burned during the fusion, serving as proof of participation in the fusion.
- Users may burn their Catalyst and SoulShard NFTs if desired.
- NFT metadata that contains information about the NFTs is stored using an off-chain URI endpoint.
- The owner may mint any number of Catalyst NFTs to any number of addresses at any time.
- The owner may toggle the ability to fuse at any time.
- The owner may lock fusion, permanently disabling it, at any time.
- The owner may change the address used to verify the signature of a fusion call at any time.
- The owner may change the URI endpoint at any time.
- The Contract is ERC-1155 compliant; all standard functionality is present.
- As the Contract is using Solidity 0.8.X, it is protected from overflows/underflows.
- No external threats were identified.
- Ensure trust in the team as they have significant control within the ecosystem.
- Date: December 10th, 2021.
Audit Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
Centralization of Control | Some off-chain logic is required. | WARNING |
Delegate Call to Untrusted Contract | N/A | PASS |
Dependence on Predictable Variables | N/A | PASS |
Deprecated Opcodes | N/A | PASS |
Ether Thief | N/A | PASS |
Exceptions | N/A | PASS |
External Calls | N/A | PASS |
Flash Loans | N/A | PASS |
Integer Over/Underflow | N/A | PASS |
Logical Issues | N/A | PASS |
Multiple Sends | N/A | PASS |
Oracles | N/A | PASS |
Suicide | N/A | PASS |
State Change External Calls | N/A | PASS |
Unbounded Loops | N/A | PASS |
Unchecked Retval | N/A | PASS |
User Supplied Assertion | N/A | PASS |
Critical Solidity Compiler | N/A | PASS |
Overall Contract Safety | PASS |
OmniFusion Contract
($) = payable function
# = non-constant function
+ [Int] IERC165
- [Ext] supportsInterface
+ [Int] IERC1155 (IERC165)
- [Ext] balanceOf
- [Ext] balanceOfBatch
- [Ext] setApprovalForAll #
- [Ext] isApprovedForAll
- [Ext] safeTransferFrom #
- [Ext] safeBatchTransferFrom #
+ [Int] IERC1155Receiver (IERC165)
- [Ext] onERC1155Received #
- [Ext] onERC1155BatchReceived #
+ [Int] IERC1155MetadataURI (IERC1155)
- [Ext] uri
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Int] verifyCallResult
+ Context
- [Int] _msgSender
- [Int] _msgData
+ ERC165 (IERC165)
- [Pub] supportsInterface
+ ERC1155 (Context, ERC165, IERC1155, IERC1155MetadataURI)
- [Pub] Constructor #
- [Pub] supportsInterface
- [Pub] uri
- [Pub] balanceOf
- [Pub] balanceOfBatch
- [Pub] setApprovalForAll #
- [Pub] isApprovedForAll
- [Pub] safeTransferFrom #
- [Pub] safeBatchTransferFrom #
- [Int] _safeTransferFrom #
- [Int] _safeBatchTransferFrom #
- [Int] _setURI #
- [Int] _mint #
- [Int] _mintBatch #
- [Int] _burn #
- [Int] _burnBatch #
- [Int] _setApprovalForAll #
- [Int] _beforeTokenTransfer #
- [Prv] _doSafeTransferAcceptanceCheck #
- [Prv] _doSafeBatchTransferAcceptanceCheck #
- [Prv] _asSingletonArray
+ Ownable (Context)
- [Pub] Constructor #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
- [Int] _transferOwnership #
+ [Int] IERC721 (IERC165)
- [Ext] balanceOf
- [Ext] ownerOf
- [Ext] safeTransferFrom #
- [Ext] transferFrom #
- [Ext] approve #
- [Ext] getApproved
- [Ext] setApprovalForAll #
- [Ext] isApprovedForAll
- [Ext] safeTransferFrom #
+ [Int] IERC721Receiver
- [Ext] onERC721Received #
+ [Int] IERC721Metadata (IERC721)
- [Ext] name
- [Ext] symbol
- [Ext] tokenURI
+ [Lib] Strings
- [Int] toString
- [Int] toHexString
- [Int] toHexString
+ ERC721 (Context, ERC165, IERC721, IERC721Metadata)
- [Pub] Constructor #
- [Pub] supportsInterface
- [Pub] balanceOf
- [Pub] ownerOf
- [Pub] name
- [Pub] symbol
- [Pub] tokenURI
- [Int] _baseURI
- [Pub] approve #
- [Pub] getApproved
- [Pub] setApprovalForAll #
- [Pub] isApprovedForAll
- [Pub] transferFrom #
- [Pub] safeTransferFrom #
- [Pub] safeTransferFrom #
- [Int] _safeTransfer #
- [Int] _exists
- [Int] _isApprovedOrOwner
- [Int] _safeMint #
- [Int] _safeMint #
- [Int] _mint #
- [Int] _burn #
- [Int] _transfer #
- [Int] _approve #
- [Int] _setApprovalForAll #
- [Prv] _checkOnERC721Received #
- [Int] _beforeTokenTransfer #
+ [Lib] ECDSA
- [Prv] _throwError
- [Int] tryRecover
- [Int] recover
- [Int] tryRecover
- [Int] recover
- [Int] tryRecover
- [Int] recover
- [Int] toEthSignedMessageHash
- [Int] toEthSignedMessageHash
- [Int] toTypedDataHash
+ [Int] IOmniFusion
- [Ext] fuseTokens #
+ [Int] IOmniFusionBurn
- [Ext] burn #
+ OmniFusion (ERC1155, IOmniFusion, IOmniFusionBurn, Ownable)
- [Pub] Constructor #
- modifiers: ERC1155
- [Pub] fuseTokens #
- [Ext] getFusionReceiptIPFSHash
- [Ext] burn #
- [Ext] mintCatalysts #
- modifiers: onlyOwner
- [Ext] setIsFusionActive #
- modifiers: onlyOwner
- [Ext] lockFusion #
- modifiers: onlyOwner
- [Ext] setFusionSigner #
- modifiers: onlyOwner
- [Ext] setURI #
- modifiers: onlyOwner
- [Prv] _mintShard #
- [Prv] _hashTransaction
- [Prv] _matchAddressSigner
- [Prv] _bytesToBytes32