SHARE

Smart Contract Audit Report

Audit Summary

SHARE Audit Report Formless is building the SHARE protocol, decentralized content distribution where content creators and collectors specify a price-per-access for premium content.

For this audit, we reviewed Formless' SHARE, S2RD, PFAUnit and PFACollection contracts at commit eab761c191144b13c6957f386a9355497f20caaa on the team's GitHub repository.

Audit Findings

Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: May 17th, 2022.
Updated: May 23rd, 2022 to reflect resolved issues by the team.

Finding #1 - PFACollection - High (Resolved)

Description: PFACollections can be initialized with addresses of PFAUnits that do not support licensing.
Risk/Impact: A malicious collection owner can profit off of PFAUnits that do not support licensings by adding them to a new collection, then taking an collection owner's fee when consumers pay to access the collection, without the permission of the PFAUnit owner.
Recommendation: The team should ensure that all PFAUnits added to a collection support licensing.
Resolution: The team has included code that requires all PFAUnits added to a collection support licensing.

Finding #2 - SHARE - Informational (Resolved)

Description: Although the SafeMath library is utilized, the contract is implemented with Solidity v0.8.x which has built-in overflow checks.
Recommendation: SafeMath could be safely removed to reduce contract size and deployment costs.
Resolution: The team has removed the SafeMath library from the code.

Contracts Overview

  • The contracts utilize ReentrancyGuard to prevent against reentrancy attacks in applicable functions.
  • As the contracts are implemented with Solidity v0.8.0, they are safe from any possible overflows/underflows.
  • The team's repository includes 53 test cases, all of which are passing.
PFAUnit Contract:
  • This contract implements a single unit of pay-for-access content as an ERC-721 NFT; it is intended to be deployed by creator of the content stored in the token URI.
  • This contract can only be deployed by an EOA account, not another contract.
  • Upon deployment, the owner is minted a single NFT. This NFT's metadata is intended to be decrypted and served to a content consumer by SHARE's Decentralized Distribution Network (DDN) based on the token URI. DDN implementation details are outside of the scope of this audit.
  • Upon initialization, the owner specifies the token URI, price-per-access, time the access is valid for, whether this unit can be licensed, and price per license; if the unit doesn't support licensing, the price per license must be zero.
  • When access is requested for this piece of content, the exact price-per-access must be passed with the function call; access is intended to only be available to the user for as long as the creator specifies.
  • The price-per-access of this content can only be changed if there is not licensing enabled; otherwise it would not be maintained that the price to access a piece of a collection never exceeds the price to access the entire collection.
  • This contract can only transfer ownership to a protocol approved wallet account or a protocol approved royalty splitting contract.
  • The owner can set the price-per-access at any time, given that licensing is not enabled.
  • The owner can set the token URI at any time.
PFACollection Contract:
  • This contract implements pay-for-access collections which consist of PFAUnits, represented as an ERC-721 NFT; for example, an artist curated NFT collection.
  • This contract can only be deployed by an EOA account, not another contract.
  • Upon deployment, the owner is minted a single NFT; there can only be one NFT created from this contract.
  • Upon initialization, the owner specifies the token URI, price per access, time the access is valid for, whether the collection can be licensed; if the collection doesn't support licensing, the price per license must be zero.
  • During initialization, the SHARE protocol is used to ensure that all specified addresses are pre-approved PFAUnit builds and that no single unit in the collection has a price per access that exceeds the collection's price per access. The collection can never exceed 199 PFAUnits.
  • When a content consumer is accessing an entire collection, they must send the exact amount of price per access of the entire collection; time to access content is effectively upgraded for all items in the collection for the consumer upon a successful access.
  • When a consumer is accessing a collection, the item that receives payment is selected incrementally based on the initial list of PFAUnit addresses specified during initialization. A low-level call is used to pay out the item owner, effectively allowing collection state to change regardless of whether the payment was received by an individual content owner.
  • The contract ensures that the owner receives their payment, which is the difference between the payment required by the selected item and the total price to access the collection. If the owner's payment is unsuccessful the entire access to the collection will revert.
  • This contract can only transfer ownership to a protocol approved wallet account.
  • The owner can set the price-per-access at any time, given that licensing is not enabled.
  • The owner can set the token URI at any time.
S2RD
  • This contract implements royalty sharing for funds received through PFAUnits.
  • This contract can only be deployed by an EOA account, not another contract.
  • Upon initialization, the contract ensures that there are no more than 199 addresses specified to participate in the royalty sharing. All addresses added must be protocol approved wallet builds.
  • The list of addresses is created by the owner off-chain. It is intended that the frequency of an address in a list is proportional to their stake held in this asset. The creation of this list is outside the scope of this audit.
  • Royalty sharing participants are incrementally paid out according to their position in the list everytime the contract receives $MATIC.
  • This contract can only have ownership transferred to a protocol approved wallet account.
  • The owner of this split contract can reclaim direct ownership of the PFAUnit who's royalties are being split by the contract; this is intended for PFAUnit maintenance purposes, e.g. updating token price & token URIs of PFAs.
SHARE
  • This contract is responsible for implementing the SHARE protocol for content distribution with creator controlled pay-for-access transactions.
  • When accesing content via the SHARE contract, users must send an exact price to access the specified contract, consisting of the creator specified price-per-access as well as a protocol fee, initially 5% of the asset's price-per-access.
  • Creators who have created content that supports licensing have the option to license either their PFAUnit or PFACollection contract to another PFACollection.
  • When a collection licenses content through this contract, the collection owner must send licensing fee specified by the licensor contract during initialization of the PFACollection or Unit, as well as a protocal fee, inititally 5% of the asset's price to license.
  • Upon deployment, the owner assigns their wallet as an approved build to be used in the contract.
  • The owner can set the transaction fee at any time.
  • The owner can withdraw all funds in the contract at any time.
  • The owner can toggle whether code verification is enabled.
  • The owner can add accounts that are approved builds of either wallets, royalty splitting contracts, PFAUnits or PFACollections.

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Jump/Storage WriteN/APASS
Centralization of Control
  • Team must manually approve contracts as interoperable with the protocol.
PASS
Compiler IssuesN/APASS
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Ether/Token TheftN/APASS
Flash LoansN/APASS
Front RunningN/APASS
Improper EventsN/APASS
Improper Authorization SchemeN/APASS
Integer Over/UnderflowN/APASS
Logical IssuesN/APASS
Oracle IssuesN/APASS
Outdated Compiler VersionN/APASS
Race ConditionsN/APASS
ReentrancyN/APASS
Signature IssuesN/APASS
Unbounded LoopsN/APASS
Unused CodeN/APASS
Overall Contract Safety PASS

PFAUnit Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function

 Int = Internal
 Ext = External
 Pub = Public

 +  ReentrancyGuard 
    - [Pub]  #

 + [Lib] Immutable 
    - [Pub] setUnsignedInt256 #
    - [Pub] setAddress #
    - [Pub] setBoolean #
    - [Pub] pushAddress #
    - [Pub] insertBooleanAtAddress #

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  Ownable (Context)
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResult

 + [Lib] CodeVerification 
    - [Pub] readCodeHash

 + [Lib] SafeMath 
    - [Int] tryAdd
    - [Int] trySub
    - [Int] tryMul
    - [Int] tryDiv
    - [Int] tryMod
    - [Int] add
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] mod
    - [Int] sub
    - [Int] div
    - [Int] mod

 + [Int] IPFA 
    - [Ext] pricePerAccess
    - [Ext] setPricePerAccess #
    - [Ext] access ($)
    - [Ext] grantTimestamp
    - [Ext] grantTTL
    - [Ext] supportsLicensing
    - [Ext] license #
    - [Ext] licenseTimestamp

 +  SHARE (Ownable, ReentrancyGuard)
    - [Pub]  #
    - [Pub] setTransactionFee #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] grossPricePerAccess
    - [Pub] access ($)
       - modifiers: nonReentrant
    - [Pub] license ($)
       - modifiers: nonReentrant
    - [Pub] grantTimestamp
    - [Pub] licenseTimestamp
    - [Pub] withdraw #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] setCodeVerificationEnabled #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] addApprovedBuild #
       - modifiers: onlyOwner,nonReentrant
    - [Pub] isApprovedBuild
    - [Pub] isApprovedBuildHash

 +  LimitedOwnable (Ownable, ReentrancyGuard)
    - [Int]  #
    - [Int] setInitialized #
       - modifiers: onlyOwner
    - [Pub] initialized
    - [Int] setShareContractAddress #
    - [Int] shareContractAddress
       - modifiers: afterInit
    - [Pub] transferOwnership #
       - modifiers: onlyOwner,afterInit

 + [Int] IPFACollection 
    - [Ext] contains

 +  PFA (IPFA, LimitedOwnable)
    - [Pub] pricePerAccess
       - modifiers: afterInit
    - [Pub] setPricePerAccess #
       - modifiers: nonReentrant,onlyOwner,afterInit
    - [Ext] access ($)
    - [Ext] supportsLicensing
       - modifiers: afterInit
    - [Pub] grantTimestamp
       - modifiers: afterInit
    - [Ext] licenseTimestamp
       - modifiers: afterInit
    - [Ext] grantTTL
       - modifiers: afterInit
    - [Pub] license #
       - modifiers: nonReentrant,afterInit

 + [Int] IERC165 
    - [Ext] supportsInterface

 + [Int] IERC721 (IERC165)
    - [Ext] balanceOf
    - [Ext] ownerOf
    - [Ext] safeTransferFrom #
    - [Ext] safeTransferFrom #
    - [Ext] transferFrom #
    - [Ext] approve #
    - [Ext] setApprovalForAll #
    - [Ext] getApproved
    - [Ext] isApprovedForAll

 + [Int] IERC721Receiver 
    - [Ext] onERC721Received #

 + [Int] IERC721Metadata (IERC721)
    - [Ext] name
    - [Ext] symbol
    - [Ext] tokenURI

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResult

 + [Lib] Strings 
    - [Int] toString
    - [Int] toHexString
    - [Int] toHexString

 +  ERC165 (IERC165)
    - [Pub] supportsInterface

 +  ERC721 (Context, ERC165, IERC721, IERC721Metadata)
    - [Pub]  #
    - [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 #
    - [Int] _afterTokenTransfer #

 +  PFAUnit (PFA, ERC721)
    - [Pub]  #
       - modifiers: ERC721,LimitedOwnable
    - [Pub] initialize #
       - modifiers: onlyOwner
    - [Pub] access ($)
       - modifiers: nonReentrant,afterInit
    - [Pub] tokenURI
    - [Pub] setTokenURI #
       - modifiers: nonReentrant,onlyOwner


PFACollection Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function

 Int = Internal
 Ext = External
 Pub = Public

  +  ReentrancyGuard 
    - [Pub]  #

 + [Lib] SafeMath 
    - [Int] tryAdd
    - [Int] trySub
    - [Int] tryMul
    - [Int] tryDiv
    - [Int] tryMod
    - [Int] add
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] mod
    - [Int] sub
    - [Int] div
    - [Int] mod

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  Ownable (Context)
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResult

 + [Lib] CodeVerification 
    - [Pub] readCodeHash

 + [Int] IPFA 
    - [Ext] pricePerAccess
    - [Ext] setPricePerAccess #
    - [Ext] access ($)
    - [Ext] grantTimestamp
    - [Ext] grantTTL
    - [Ext] supportsLicensing
    - [Ext] license #
    - [Ext] licenseTimestamp

 +  SHARE (Ownable, ReentrancyGuard)
    - [Pub]  #
    - [Pub] setTransactionFee #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] grossPricePerAccess
    - [Pub] access ($)
       - modifiers: nonReentrant
    - [Pub] license ($)
       - modifiers: nonReentrant
    - [Pub] grantTimestamp
    - [Pub] licenseTimestamp
    - [Pub] withdraw #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] setCodeVerificationEnabled #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] addApprovedBuild #
       - modifiers: onlyOwner,nonReentrant
    - [Pub] isApprovedBuild
    - [Pub] isApprovedBuildHash

 + [Lib] Immutable 
    - [Pub] setUnsignedInt256 #
    - [Pub] setAddress #
    - [Pub] setBoolean #
    - [Pub] pushAddress #
    - [Pub] insertBooleanAtAddress #

 +  LimitedOwnable (Ownable, ReentrancyGuard)
    - [Int]  #
    - [Int] setInitialized #
       - modifiers: onlyOwner
    - [Pub] initialized
    - [Int] setShareContractAddress #
    - [Int] shareContractAddress
       - modifiers: afterInit
    - [Pub] transferOwnership #
       - modifiers: onlyOwner,afterInit

 + [Int] IPFACollection 
    - [Ext] contains

 +  PFA (IPFA, LimitedOwnable)
    - [Pub] pricePerAccess
       - modifiers: afterInit
    - [Pub] setPricePerAccess #
       - modifiers: nonReentrant,onlyOwner,afterInit
    - [Ext] access ($)
    - [Ext] supportsLicensing
       - modifiers: afterInit
    - [Pub] grantTimestamp
       - modifiers: afterInit
    - [Ext] licenseTimestamp
       - modifiers: afterInit
    - [Ext] grantTTL
       - modifiers: afterInit
    - [Pub] license #
       - modifiers: nonReentrant,afterInit

 + [Int] IERC165 
    - [Ext] supportsInterface

 + [Int] IERC721 (IERC165)
    - [Ext] balanceOf
    - [Ext] ownerOf
    - [Ext] safeTransferFrom #
    - [Ext] safeTransferFrom #
    - [Ext] transferFrom #
    - [Ext] approve #
    - [Ext] setApprovalForAll #
    - [Ext] getApproved
    - [Ext] isApprovedForAll

 + [Int] IERC721Receiver 
    - [Ext] onERC721Received #

 + [Int] IERC721Metadata (IERC721)
    - [Ext] name
    - [Ext] symbol
    - [Ext] tokenURI

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResult

 + [Lib] Strings 
    - [Int] toString
    - [Int] toHexString
    - [Int] toHexString

 +  ERC165 (IERC165)
    - [Pub] supportsInterface

 +  ERC721 (Context, ERC165, IERC721, IERC721Metadata)
    - [Pub]  #
    - [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 #
    - [Int] _afterTokenTransfer #

 +  PFACollection (PFA, IPFACollection, ERC721)
    - [Pub]  #
       - modifiers: ERC721,LimitedOwnable
    - [Pub] initialize #
       - modifiers: onlyOwner
    - [Pub] addressIndex
       - modifiers: afterInit
    - [Pub] access ($)
       - modifiers: nonReentrant,afterInit
    - [Pub] contains
       - modifiers: afterInit
    - [Pub] tokenURI
    - [Pub] setTokenURI #
       - modifiers: nonReentrant,onlyOwner


S2RD Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function

 Int = Internal
 Ext = External
 Pub = Public

   + [Lib] Immutable 
    - [Pub] setUnsignedInt256 #
    - [Pub] setAddress #
    - [Pub] setBoolean #
    - [Pub] pushAddress #
    - [Pub] insertBooleanAtAddress #

 +  ReentrancyGuard 
    - [Pub]  #

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  Ownable (Context)
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResult

 + [Lib] CodeVerification 
    - [Pub] readCodeHash

 + [Lib] SafeMath 
    - [Int] tryAdd
    - [Int] trySub
    - [Int] tryMul
    - [Int] tryDiv
    - [Int] tryMod
    - [Int] add
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] mod
    - [Int] sub
    - [Int] div
    - [Int] mod

 + [Int] IPFA 
    - [Ext] pricePerAccess
    - [Ext] setPricePerAccess #
    - [Ext] access ($)
    - [Ext] grantTimestamp
    - [Ext] grantTTL
    - [Ext] supportsLicensing
    - [Ext] license #
    - [Ext] licenseTimestamp

 +  SHARE (Ownable, ReentrancyGuard)
    - [Pub]  #
    - [Pub] setTransactionFee #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] grossPricePerAccess
    - [Pub] access ($)
       - modifiers: nonReentrant
    - [Pub] license ($)
       - modifiers: nonReentrant
    - [Pub] grantTimestamp
    - [Pub] licenseTimestamp
    - [Pub] withdraw #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] setCodeVerificationEnabled #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] addApprovedBuild #
       - modifiers: onlyOwner,nonReentrant
    - [Pub] isApprovedBuild
    - [Pub] isApprovedBuildHash

 +  LimitedOwnable (Ownable, ReentrancyGuard)
    - [Int]  #
    - [Int] setInitialized #
       - modifiers: onlyOwner
    - [Pub] initialized
    - [Int] setShareContractAddress #
    - [Int] shareContractAddress
       - modifiers: afterInit
    - [Pub] transferOwnership #
       - modifiers: onlyOwner,afterInit

 +  S2RD (LimitedOwnable)
    - [Pub]  #
       - modifiers: LimitedOwnable
    - [Pub] initialize #
       - modifiers: onlyOwner
    - [Pub] addressIndex
       - modifiers: afterInit
    - [Ext]  ($)
       - modifiers: nonReentrant,afterInit


SHARE Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = payable function
 # = non-constant function

 Int = Internal
 Ext = External
 Pub = Public

  + [Lib] SafeMath 
    - [Int] tryAdd
    - [Int] trySub
    - [Int] tryMul
    - [Int] tryDiv
    - [Int] tryMod
    - [Int] add
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] mod
    - [Int] sub
    - [Int] div
    - [Int] mod

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  Ownable (Context)
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 +  ReentrancyGuard 
    - [Pub]  #

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResult

 + [Lib] CodeVerification 
    - [Pub] readCodeHash

 + [Int] IPFA 
    - [Ext] pricePerAccess
    - [Ext] setPricePerAccess #
    - [Ext] access ($)
    - [Ext] grantTimestamp
    - [Ext] grantTTL
    - [Ext] supportsLicensing
    - [Ext] license #
    - [Ext] licenseTimestamp

 +  SHARE (Ownable, ReentrancyGuard)
    - [Pub]  #
    - [Pub] setTransactionFee #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] grossPricePerAccess
    - [Pub] access ($)
       - modifiers: nonReentrant
    - [Pub] license ($)
       - modifiers: nonReentrant
    - [Pub] grantTimestamp
    - [Pub] licenseTimestamp
    - [Pub] withdraw #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] setCodeVerificationEnabled #
       - modifiers: nonReentrant,onlyOwner
    - [Pub] addApprovedBuild #
       - modifiers: onlyOwner,nonReentrant
    - [Pub] isApprovedBuild
    - [Pub] isApprovedBuildHash

About SourceHat

SourceHat has quickly grown to have one of the most experienced and well-equipped smart contract auditing teams in the industry. Our team has conducted 1800+ solidity smart contract audits covering all major project types and protocols, securing a total of over $50 billion U.S. dollars in on-chain value!
Our firm is well-reputed in the community and is trusted as a top smart contract auditing company for the review of solidity code, no matter how complex. Our team of experienced solidity smart contract auditors performs audits for tokens, NFTs, crowdsales, marketplaces, gambling games, financial protocols, and more!

Contact us today to get a free quote for a smart contract audit of your project!

What is a SourceHat Audit?

Typically, a smart contract audit is a comprehensive review process designed to discover logical errors, security vulnerabilities, and optimization opportunities within code. A SourceHat Audit takes this a step further by verifying economic logic to ensure the stability of smart contracts and highlighting privileged functionality to create a report that is easy to understand for developers and community members alike.

How Do I Interpret the Findings?

Each of our Findings will be labeled with a Severity level. We always recommend the team resolve High, Medium, and Low severity findings prior to deploying the code to the mainnet. Here is a breakdown on what each Severity level means for the project:

  • High severity indicates that the issue puts a large number of users' funds at risk and has a high probability of exploitation, or the smart contract contains serious logical issues which can prevent the code from operating as intended.
  • Medium severity issues are those which place at least some users' funds at risk and has a medium to high probability of exploitation.
  • Low severity issues have a relatively minor risk association; these issues have a low probability of occurring or may have a minimal impact.
  • Informational issues pose no immediate risk, but inform the project team of opportunities for gas optimizations and following smart contract security best practices.