May 27th 2022 — Quantstamp Verified

Bitcoin.com
This audit report was prepared by Quantstamp, the leader in blockchain security.

Executive Summary
Type

Token Distribution Contract

Auditors

David Knott, Senior Research Engineer
Alejandro Padilla Gaeta, Research Engineer
Rabib Islam, Research Engineer

Timeline

2022-04-22 through 2022-05-27

EVM

Arrow Glacier

Languages

Solidity

Methods

Architecture Review, Unit Testing, Computer-Aided
Verification, Manual Review

Specification

High Risk

The issue puts a large number of users’
sensitive information at risk, or isreasonably likely to lead to catastrophic
impact for client’s reputation or serious
financial implications for client andusers.

Medium Risk

The issue puts a subset of users’
sensitive information at risk, would be
detrimental for the client’s reputation if
exploited, or is reasonably likely to leadto moderate financial impact.

Low Risk

The risk is relatively small and could not
be exploited on a recurring basis, or is arisk that the client has indicated is lowimpact in view of the client’s businesscircumstances.

Informational

The issue does not post an immediaterisk, but is relevant to security bestpractices or Defence in Depth.

Undetermined

The impact of the issue is uncertain.

Unresolved

Acknowledged the existence of the risk,
and decided to accept it without
engaging in special efforts to control it.

Acknowledged

The issue remains in the code but is a
result of an intentional business ordesign decision. As such, it is supposed
to be addressed outside theprogrammatic means, such as: 1)
comments, documentation, README,
FAQ; 2) business processes; 3) analyses
showing that the issue shall have no
negative consequences in practice(e.g., gas analysis, deployment
settings).

Fixed

Adjusted program implementation,requirements or constraints to eliminate
the risk.

Mitigated

Implemented actions to minimize theimpact or likelihood of the risk.

None

Documentation Quality

Low

Test Quality

High

Source Code
Repository

Commitverse-token-contracts

0309a48

verse-token-contracts

99bc608

verse-token-contracts

3950501

Total Issues

7 (5 Resolved)

High Risk Issues

0 (0 Resolved)

Medium Risk Issues

0 (0 Resolved)

Low Risk Issues

2 (1 Resolved)

Informational Risk Issues

4 (4 Resolved)

Undetermined Risk Issues

1 (0 Resolved)

Summary of Findings
Quantstamp has performed a security audit of the VerseToken and VerseClaimer contracts and has identified 7 security issues ranging from Low to Undetermined risk levels.
Additionally, we have found 3 documentation and 7 best practice issues. We recommend addressing all issues before deploying the smart contracts in production.

ID

Description

Severity

Status

QSP-1

Transfers To Zero Address

Low

Acknowledged

QSP-2

Undocumented Token Distribution Funding

Low

Fixed

QSP-3

Missing Constructor Argument Validation

Informational

Fixed

QSP-4

Gas Usage / Loop Concerns

Informational

Fixed

QSP-5

Untrusted Token Double Claim

Informational

Fixed

QSP-6

Signature Malleability

Informational

Fixed

QSP-7

Unrestricted Burns

Undetermined

Acknowledged

Quantstamp Audit Breakdown
Quantstamp's objective was to evaluate the repository for security-related issues, code quality, and adherence to specification and best practices.
Possible issues we looked for included (but are not limited to):• Transaction-ordering dependence• Timestamp dependence• Mishandled exceptions and call stack limits• Unsafe external calls• Integer overflow / underflow• Number rounding errors• Reentrancy and cross-function vulnerabilities• Denial of service / logical oversights• Access control• Centralization of power• Business logic contradicting the specification• Code clones, functionality duplication• Gas usage• Arbitrary token minting

Methodology
The Quantstamp auditing process follows a routine series of steps:
1.

2.

3.

Code review that includes the followingi.

Review of the specifications, sources, and instructions provided to Quantstamp to make sure we understand the size, scope, and functionality of the smart contract.

ii.

Manual review of code, which is the process of reading source code line-by-line in an attempt to identify potential vulnerabilities.

iii.

Comparison to specification, which is the process of checking whether the code does what the specifications, sources, and instructions provided to Quantstamp describe.

Testing and automated analysis that includes the following:i.

Test coverage analysis, which is the process of determining whether the test cases are actually covering the code and how much code is exercised when we run those test cases.

ii.

Symbolic execution, which is analyzing a program to determine what inputs cause each part of a program to execute.

Best practices review, which is a review of the smart contracts to improve efficiency, effectiveness, clarify, maintainability, security, and control based on the established industry andacademic practices, recommendations, and research.

4.

Specific, itemized, and actionable recommendations to help you take steps to secure your smart contracts.

ToolsetThe notes below outline the setup and steps performed in the process of this audit.
Setup
Tool Setup:• Slither v0.8.3
Steps taken to run the tools:
1. Installed the Slither tool: pip install slither-analyzer
2. Run Slither from the project directory: slither contracts

Findings
QSP-1 Transfers To Zero Address

Severity: Low Risk
Status: AcknowledgedFile(s) affected: VerseToken.sol
Description: Operations in the VerseToken contract do not verify that the addresses tokens are sent to are not address(0). In particular, this might be a problem for the _transfer function
as any tokens sent by mistake to the address(0) will be irrecoverable.
Recommendation: Validate that the VerseToken::L196(transfer) and VerseToken::L212(transferFrom) operations are not transferring tokens to address(0).
Update: The Bitcoin.com team acknowledges the issue and states that they have chosen not to check for address(0) token sends to save gas and that wallets interfacing with theVerseToken contract are expected to check for address(0) token sends.

QSP-2 Undocumented Token Distribution Funding
Severity: Low Risk
Status: Fixed
File(s) affected: VerseClaimer.sol
Description: Before participants can be enrolled (and have their tokens scraped), the VerseClaimer contract must have enough VerseTokens assigned to it; otherwise calls to
VerseHelper::L75(_checkVerseBalance) will fail and participants will not be able to claim their tokens. It is unclear how and when the VerseClaimer will receive these funds.
Recommendation: Add technical and end-user documentation specifying how VerseClaimer will be funded with VerseTokens.
Update: VerseToken's constructor was modified to instantiate the VerseClaimer contract and mint _initialSupply directly to it.

QSP-3 Missing Constructor Argument Validation
Severity: Informational
Status: Fixed
File(s) affected: VerseClaimer.sol
Description: VerseClaimer::L24(constructor) takes in _verseTokenAddress and _merkleRoot as arguments but does not check that _verseTokenAddress is a smart contract
and that _merkleRoot is not a null byte string. The incorrect setting of any of VerseClaimer::L24(constructor)'s arguments would require a redeployment of VerseClaimer.
Recommendation: Modify VerseClaimer::L24(constructor) to require _verseTokenAddress to be a contract address and _merkleRoot to not be a null byte string. Consider using
OpenZeppelin’s isContract() function to perform the contract check.

QSP-4 Gas Usage / Loop Concerns
Severity: Informational
Status: Fixed
File(s) affected: VerseClaimer.sol
Related Issue(s): SWC-126, SWC-134
Description: Gas usage is a main concern for smart contract developers and users, since high gas costs may prevent users from wanting to use the smart contract. Even worse, some gas usage
issues may prevent the contract from providing services entirely. For example, if a loop requires too much gas to finish processing, then it may prevent the contract from functioning correctly
entirely.
The VerseClaimer::L61(enrollRecipientBulk) performs unbounded iteration over multiple arrays which may lead VerseClaimer::L61(enrollRecipientBulk) calls to run out
of gas. Furthermore, the usage of multiple arrays increases the chances of caller error.
Recommendation: Add an upper bound to the number of enrollments that VerseClaimer::L61(enrollRecipientBulk) can process. Additionally, modify
VerseClaimer::L61(enrollRecipientBulk) to receive a struct instead of a list for each parameter to increase readability and safety of usage.
Update: An upper bound of 10 enrollments was added to enrollRecipientBulk.

QSP-5 Untrusted Token Double Claim
Severity: Informational
Status: Fixed
File(s) affected: VerseClaimer.sol
Description: This issue has been classified as informational as it is only relevant if a malicious ERC20 is used as VerseClaim’s verseToken instead of the VerseToken smart contract.
A reentrancy exploit can occur when external contract calls are made. To protect against reentrancy, it is recommended to order one’s functions by:• checks - Perform validation checks.
• effects - Update all contract state.
• interactions - Make external contract calls.
The above ordering protects one’s functions from reentrancy because by the time external contract calls are made and execution is given to a potentially untrusted contract, all contract state isalready in the most up-to-date state.
Double claims are protected against by requiring keeperList[_recipient].keeperTill to be equal to 0. VerseClaimer::L125(_allocateTokens) performs an external contract
call to verseToken to check VerseClaimer's token balance prior to setting keeperTill. If an attacker can acquire control of execution from verseToken they will be able to re-claim bycalling _enrollRecipient multiple times before keeperTill is set.
Recommendation: Set keeperTill before checking VerseClaimer’s token balance to align with the checks/effects/interactions pattern. The balance check call should also use staticcall
instead of call as it calls a non-state changing function.
Update: VerseClaimers's _allocateTokens's _checkVerseBalance external contract call was moved to be called after all the contract's internal state has been updated and is now inline with the checks/effects/interactions pattern.

QSP-6 Signature Malleability
Severity: Informational
Status: Fixed
File(s) affected: VerseToken.sol
Description: EIP-2 allows signature malleability for ecrecover(). VerseToken::L233(permit) accepts malleable signatures, allowing a signature different from the one an owner signed
to be successfully submitted. This would make the permitting transaction hash different from the one the permit signer is expecting.
Recommendation: Modify VerseToken::L233(permit)'s owner signature check to require unique signatures by requiring signature s-values to be in the lower half of the potential range.
The Ethereum Yellow paper (EY) defines s-value's full range as:* 0 < s < secp256k1n ÷ 2 + 1 (EY 311)
* With secp256k1n = 115792089237316195423570985008687907852837564279074904382605163141518161494337 (EY 313)

Open Zeppelin's ECDSA contract which checks signature uniqueness can be used as a reference.
Update: VerseToken's permit checks for and reverts if a signature's s-value is in the upper half of its potential range. This disables signature malleability.

QSP-7 Unrestricted Burns
Severity: Undetermined
Status: AcknowledgedFile(s) affected: VerseToken.sol
Description: VerseToken::L78(burn)is not restricted; anyone can call it to burn their tokens. While this functionality is okay by itself, the Verse leadership’s supply mechanism might beaffected if too many tokens are burnt without their consent (the Verse white paper describes that there is a carefully designed supply mechanism planned).
Recommendation: Evaluate if the planned supply mechanism can be impacted by individual users burning their own tokens. If it is a problem, restrict VerseToken::L78(burn)method accessto a whitelist of users controlled by Verse.
Update: The Bitcoin.com team acknowledges the issue and states that they intend for anyone to be able to burn tokens.

Automated Analyses
SlitherSlither has detected 105 results out of which most have been filtered out as false positives. The true positives have been incorporated in the findings above.

Code Documentation
1. There’s no documentation anywhere in the codebase. While most of the code is quite straightforward, it is still a good practice to document the code for improved readability andmaintainability. We recommend following the NatSpec Format.
2. Add documentation explaining why overflow/underflow protection is not necessary for VerseToken’s unchecked blocks.
3. Modify VerseClaimer's minimum and maximum calculations to use OpenZeppelin's min and max functions to increase readability.
Update: No Code Documentation related code changes were found in the re-audit.

Adherence to Best Practices
1. Most of the implementation of the project can be replaced with code from existing audited third-party libraries. For example, most of VerseToken's functionality can be replaced with
OpenZeppelin’s ERC20 implementation (VerseToken would have to inherit from the ERC20.sol contract). Similarly, MerkleProof.sol can be replaced with a call to
OpenZeppelin’s own implementation.
2. It would be more legible to use a require statement instead of revert on VerseHelper::L27. That way both the condition and the error message would be part of the same statement.
3. If the scrapeAmount on L200 of the VerseClaimer contract is 0 then execution beyond it is a no operation (no-op). Add validation on L203 to save gas by preventing the no-op frombeing executed.
4. Modify VerseClaimer to use OpenZeppelin's IERC20 interface to interact with VerseToken instead of manually calculating the function signatures and using the low-level callkeyword. The usage of call makes the code less readable and is more error prone. If there is a reason to use call add technical documentation explaining the reason.
5. The ERC20 standard’s approve functionality is vulnerable to double spending when an existing allowance is being updated. If a transaction claiming the old allowance is included
before the transaction updating the allowance then both the old allowance and the new allowance can be claimed. Add end-user documentation explaining the double-spend vulnerability
and recommending users use decreaseAllowance and increaseAllowance when modifying a non-zero allowance.
6. Modify VerseToken::L233(permit) to accept EIP-2098 compact signatures where the signature's r , s and v values are stored compactly within 64 bytes.
Best Practices Found in Re-Audit
1. VerseClaimer contract constructor only validates that the _minimumTimeFrame is larger than 0. Therefore, it can be set to impractically low values, thereby allowing tokens to be
scrapped, for all intents and purposes, immediately (e.g., if we set the value to 1 the tokens would be available to be scrapped a second afterwards). Add validation to VerseClaimer's
constructor checking that _minimumTimeFrame is greater than a preconfigured minimum time frame value constant.
Update: No Best Practices related code changes were found in the re-audit.

Test Results
Test Suite Results

Contract: VerseClaimer
Token Claimer✓ should be able to store merkle root
✓ should be able to store token address✓ should set createTime as blocktime (39ms)✓ should revert if token address is invalid (247ms)✓ should revert if timeframe is invalid (123ms)
Token Claiming Functionality✓ should be able to enroll (129ms)✓ should be able to enroll bulk (110ms)✓ should not allow to enroll the same recipient twice (80ms)✓ should not allow to enroll zero time entry (40ms)✓ should not allow to enroll invalid values (162ms)✓ should increase totalRequired after each entroll (99ms)✓ should decrease totalRequired after each scrape (201ms)✓ should store correct values (99ms)✓ should be able enroll and scrape tokens generate two events (60ms)✓ should throw error if working with dead token (74ms)✓ should not allow to create allocations if contract is not funded (253ms)✓ should be able to query remaining balance locked (50ms)
Contract: VerseToken
Token Initial Values✓ should have correct token name✓ should have correct token symbol✓ should have correct token decimals✓ should have correct token supply✓ should return the correct balance for the given account✓ should return the correct allowance for the given spender
Token Transfer Functionality✓ should transfer correct amount from walletA to walletB✓ should revert if not enough balance in the wallet✓ should reduce wallets balance after transfer (39ms)✓ should emit correct Transfer event✓ should update the balance of the recipient when using transferFrom (68ms)✓ should deduct from the balance of the sender when using transferFrom (73ms)✓ should revert if there is no approval when using transferFrom✓ should revert if the sender has spent more than their approved amount when using transferFrom (53ms)
Token Approval Functionality✓ should assign value to allowance mapping✓ should emit a correct Approval event (41ms)✓ should allow to increase allowance (73ms)✓ should allow to decrease allowance (79ms)✓ should not change allowance if its at maximum (118ms)
Burn Functionality✓ should reduce the balance of the wallet thats burnng the tokens (40ms)✓ should not allow to burn more than user have (77ms)✓ should deduct the correct amount from the total supply (43ms)
Permit Functionality✓ revert if invalid permit() (53ms)✓ should allow to adjust allowance through valid permit() (76ms)✓ revert if invalid deadline (46ms)

42 passing (9s)Code Coverage
npm run coverage was ran to determine test coverage.

File% Stmts% Branch% Funcs% Lines

100

100

100

100

MerkleProof.sol

100

100

100

100

VerseClaimer.sol

100

100

100

100

VerseHelper.sol

100

100

100

100

VerseToken.sol

100

100

100

100

100

100

100

100

contracts/

All files

Changelog• 2022-04-22 - Initial report• 2022-05-17 - Re-audit• 2022-05-27 - Test coverage increase

Uncovered LinesAbout Quantstamp
Quantstamp is a Y Combinator-backed company that helps to secure blockchain platforms at scale using computer-aided reasoning tools, with a mission to help boost the
adoption of this exponentially growing technology.
With over 1000 Google scholar citations and numerous published papers, Quantstamp's team has decades of combined experience in formal verification, static analysis,
and software verification. Quantstamp has also developed a protocol to help smart contract developers and projects worldwide to perform cost-effective smart contract
security scans.
To date, Quantstamp has protected $5B in digital asset risk from hackers and assisted dozens of blockchain projects globally through its white glove security assessment
services. As an evangelist of the blockchain ecosystem, Quantstamp assists core infrastructure projects and leading community initiatives such as the Ethereum
Community Fund to expedite the adoption of blockchain technology.
Quantstamp's collaborations with leading academic institutions such as the National University of Singapore and MIT (Massachusetts Institute of Technology) reflect ourcommitment to research, development, and enabling world-class blockchain security.

Timeliness of content
The content contained in the report is current as of the date appearing on the report and is subject to change without notice, unless indicated otherwise by Quantstamp;
however, Quantstamp does not guarantee or warrant the accuracy, timeliness, or completeness of any report you access using the internet or other means, and assumes
no obligation to update any information following publication.
Notice of confidentiality
This report, including the content, data, and underlying methodologies, are subject to the confidentiality and feedback provisions in your agreement with Quantstamp.
These materials are not to be disclosed, extracted, copied, or distributed except to the extent expressly authorized by Quantstamp.
Links to other websites
You may, through hypertext or other computer links, gain access to web sites operated by persons other than Quantstamp, Inc. (Quantstamp). Such hyperlinks areprovided for your reference and convenience only, and are the exclusive responsibility of such web sites' owners. You agree that Quantstamp are not responsible for thecontent or operation of such web sites, and that Quantstamp shall have no liability to you or any other person or entity for the use of third-party web sites. Except as
described below, a hyperlink from this web site to another web site does not imply or mean that Quantstamp endorses the content on that web site or the operator oroperations of that site. You are solely responsible for determining the extent to which you may use any content at any other web sites to which you link from the report.
Quantstamp assumes no responsibility for the use of third-party software on the website and shall have no liability whatsoever to any person or entity for the accuracy orcompleteness of any outcome generated by such software.
Disclaimer
This report is based on the scope of materials and documentation provided for a limited review at the time provided. Results may not be complete nor inclusive of all
vulnerabilities. The review and this report are provided on an as-is, where-is, and as-available basis. You agree that your access and/or use, including but not limited to any
associated services, products, protocols, platforms, content, and materials, will be at your sole risk. Blockchain technology remains under development and is subject tounknown risks and flaws. The review does not extend to the compiler layer, or any other areas beyond the programming language, or other programming aspects that
could present security risks. A report does not indicate the endorsement of any particular project or team, nor guarantee its security. No third party should rely on thereports in any way, including for the purpose of making any decisions to buy or sell a product, service or any other asset. To the fullest extent permitted by law, we disclaim
all warranties, expressed or implied, in connection with this report, its content, and the related services and products and your use thereof, including, without limitation, theimplied warranties of merchantability, fitness for a particular purpose, and non-infringement. We do not warrant, endorse, guarantee, or assume responsibility for any
product or service advertised or offered by a third party through the product, any open source or third-party software, code, libraries, materials, or information linked to,called by, referenced by or accessible through the report, its content, and the related services and products, any hyperlinked websites, any websites or mobile applications
appearing on any advertising, and we will not be a party to or in any way be responsible for monitoring any transaction between you and any third-party providers of
products or services. As with the purchase or use of a product or service through any medium or in any environment, you should use your best judgment and exercise
caution where appropriate. FOR AVOIDANCE OF DOUBT, THE REPORT, ITS CONTENT, ACCESS, AND/OR USAGE THEREOF, INCLUDING ANY ASSOCIATED SERVICES OR
MATERIALS, SHALL NOT BE CONSIDERED OR RELIED UPON AS ANY FORM OF FINANCIAL, INVESTMENT, TAX, LEGAL, REGULATORY, OR OTHER ADVICE.

Bitcoin.com Audit