1 Summary
ConsenSys Diligence conducted a security audit on the Vega token, an ERC20 compliant token for the Vega protocol, a protocol for creating and trading derivatives on a fully decentralized network.
Audit Changelog | Date |
---|---|
Initial report delivery. | 2020-01-29 |
Diff highlighting fixes of the issues raised in the report was provided by the Vega team. | 2020-02-10 |
Fixes acknowledged by the audit team and final report delivery. | 2020-02-12 |
2 Audit Scope
This audit covered the following files:
Source repository commit# : vega-protocol/vega_token.git#672d747e2f38cd9f51ee7b4cd99ceb02a3573bfb
File Name | SHA-1 Hash |
---|---|
contracts/Vega_Token.sol | b92b3c54b2f47a88fa9e84534046b462dbaee9aa |
contracts/Address.sol | 1213b0f150dd5e3f694c3721c44cb5cc3202b743 |
contracts/ERC20Detailed.sol | 7e4d00c462120565201f28361b29201d1bfe0a34 |
contracts/IERC20.sol | 72c15b6a16b7dc92e69ff97ccfe1958d9948e200 |
contracts/ERC20Lockable.sol | 377447995444beee2b3c5342bfa9b1bbc1d08356 |
contracts/SafeMath.sol | c8bda5eb19c16d34bc48bf115229a9b967feb6ef |
contracts/ERC20StaticSupply.sol | bf3e66af74470eed08d0e0f82b9a98705a745c7c |
contracts/Ownable.sol | 12ec51ec8a3b4eed6326434fd0f5926b40602778 |
contracts/Roles.sol | 2c85acf184ae36f96ebafd8f6e26232ea459a711 |
contracts/SafeERC20.sol | ebd65ea9a0cdcb29bbbbf651a1076d51be031443 |
- contracts/Roles.sol
- is an unmodified copy of OpenZeppelin/contracts/access/Roles.sol#67bca85.
- is the latest version available to date.
- is not referenced throughout the codebase.
- contracts/Address.sol
- is an unmodified copy of OpenZeppelin/contracts/utils/Address.sol#18d7e24.
- is not the latest version available to date.
- contracts/SafeERC20.sol
- is an copy of OpenZeppelin/contracts/token/ERC20/SafeERC20.sol#5d34dbe with minor modifications (adjusted import pragma).
- is not referenced throughout the codebase
- contracts/Ownable.sol
- is a copy of OpenZeppelin/contracts/ownership/Ownable.sol#f095b62 with no logic changing modifications to the contract.
- contracts/SafeMath.sol
- is a copy of OpenZeppelin/contracts/math/SafeMath.sol#c4bb7b7 with no logic changing modifications to the contract.
- contracts/IERC20.sol, contracts/ERC20Detailed.sol
- are a unmodified copies of
The audit activities can be grouped into the following three broad categories:
- Security: Identifying security related issues within the contract.
- Architecture: Evaluating the system architecture through the lens of established smart contract best practices.
- Code quality: A full review of the contract source code. The primary areas of focus include:
- Correctness
- Readability
- Scalability
- Code complexity
- Quality of test coverage
3 System Overview
This section describes the top-level contracts, their inheritance structure, actors, permissions and contract interactions. Please refer to section 5 - Security Specification for a security-centric view on the system.
Inheritance Structure
Call Graph
Vega Token
4 Key Observations/Recommendations
-
The following libraries are part of the project workspace but not referenced by the Vega Token:
Roles.sol
SafeERC20.sol
and therefore alsoAddress.sol
which is only referenced bySafeERC20.sol
- Acknowledged and fixed by the development team.
-
SWC-103: The codebase sets compiler flags (
pragma solidity ^0.5.0
) that allows compilation with any soldity 0.5.x compiler potentially allowing to fall back to untested versions or compiler versions with known bugs, vulnerabilities or fewer security checks. It is recommended to lock the version to the solidity compiler version the codebase has been thoroughly tested.- Please note that the latest solidity compiler version released is v0.6.2.
- Acknowledged and fixed by the development team.
-
ERC20Lockable.unlock_date
should be declaredconstant
and all uppercaseuint256 public constant UNLOCK_DATE = 1609459199;
.- Acknowledged and fixed by the development team. (v. Issue 6.1)
-
ERC20StaticSupply.constructor()
could usesuper().mint(address(this), to_mint)
instead of duplicating code.- Acknowledged and fixed by the development team.
-
The contract
Vega_Token
should be named using CapWords as recommended by the solidity style guide.- Acknowledged and fixed by the development team.
5 Security Specification
This section describes the behavior of the system under audit from a security perspective. It is best combined with the overview given in section 3 - System Overview. Please note that this document is not a substitute for documentation. The purpose of this section is to identify specific security properties that were validated by the audit team. Furthermore, the information contained in this section can be used for internal security activities and we recommend documenting and building-upon the trust model that has been established.
5.1 Actors
The relevant actors are as follows:
- Deployer - initially deploys the system.
- Owner - privileged account that is used to distribute tokens.
- Token Holder - address with a token balance > 0.
- Any Ethereum Account - address with no token balance.
5.2 Trust Model
In any smart contract system, it’s important to identify what trust is expected/required between various actors. For this audit, we established the following trust model:
-
Deployer initially deploys the smart contract system.
Vega Token
isOwnable
and therefore turns the Deployer into the Owner in control of the Token.- An amount of tokens is initially minted and assigned to the
Vega Token
contract address.- New tokens cannot be minted after the deployment phase.
- Existing tokens cannot be burned.
- Token Supply is static throughout the lifetime of the token.
- Transfers for Token Holders of the
Vega Token
are initially locked. - Token transfers are automatically unlocked after a hardcoded
unlock_date
.
- An amount of tokens is initially minted and assigned to the
-
Owner can manually unlock the token before
unlock_date
has passed, allowing Token Holders to start transferring their tokens. -
Owner can issue any amount of tokens owned by the
Vega Token
contract address to Token Holder or Any Ethereum Account. -
Owner can issue tokens after the
unlock_date
has passed. -
Owner can renounce ownership of the contract leaving the contract unmanaged.
-
Owner can transfer ownership of the contract to Any Ethereum Account.
-
Owner cannot burn tokens.
-
Owner cannot mint new tokens and therefore change supply.
-
Owner can unlock token transfers immediately after deployment.
-
Token Holders can transfer tokens to Any Ethereum Account if the token is unlocked (either
unlock_date
has passed or token is manually unlocked by Owner). -
Token Holders can approve and change token approvals also before the token trading is unlocked.
5.3 Important Security Properties
The following is a non-exhaustive list of security properties that were verified in this audit:
ERC20
Tokenname
,symbol
,decimals
andtotalSupply
is constant throughout the lifetime of the Token.- The sum of all tokens in circulations equals the
totalSupply
set for the token. - Only the Owner can mint tokens.
- Tokens are only minted and assigned to the
Vega Token
contract address when creating the contract.
- The sum of all tokens in circulations equals the
- Token Holders are in control of their token balances. An administrative account (Owner) cannot interfere (transfer/burn) with Token Holder’s token balances.
- Only the Owner can transfer/renounce ownership of the contract.
- Transferring ownership allows the new owner to issue tokens on behalf of the
Vega Token
contract or unlock the token if it is not yet unlocked.
- Transferring ownership allows the new owner to issue tokens on behalf of the
- Renouncing ownership removes Owner ability to manage the contract.
- Former Owner loses the ability to assign tokens held by the
Vega Token
contract to new Token Holders. - Former Owner loses the ability to manually unlock the token.
- A new Owner cannot be assigned after renouncing ownership.
- If the ownership is renounced while the contract is still locked, Token Holders can exercise their right to transfer tokens but only after
unlock_date
has passed which automatically unlocks the token.
- Former Owner loses the ability to assign tokens held by the
- The contract cannot be selfdestruct.
6 Issues
Each issue has an assigned severity:
- Minor issues are subjective in nature. They are typically suggestions around best practices or readability. Code maintainers should use their own judgment as to whether to address such issues.
- Medium issues are objective in nature but are not security vulnerabilities. These should be addressed unless there is a clear reason not to.
- Major issues are security vulnerabilities that may not be directly exploitable or may require certain conditions in order to be exploited. All major issues should be addressed.
- Critical issues are directly exploitable security vulnerabilities that need to be fixed.
6.1 ERC20Lockable - inconsistent locking status Minor ✓ Fixed
Resolution
Description
Vega_Token.is_tradable()
will incorrectly return false
if the token is never manually unlocked by the owner but unlock_time
has passed, which will automatically unlock trading.
Examples
code/ERC20Lockable.sol:L48-L67
/**
* @dev locked status, only applicable before unlock_date
*/
bool public _is_locked = true;
/**
* @dev Modifier that only allows function to run if either token is unlocked or time has expired.
* Throws if called while token is locked.
*/
modifier onlyUnlocked() {
require(!_is_locked || now > unlock_date);
_;
}
/**
* @dev Internal function that unlocks token. Can only be ran before expiration (give that it's irrelevant after)
*/
function _unlock() internal {
require(now <= unlock_date);
_is_locked = false;
Recommendation
- declare
_is_locked
asprivate
instead ofpublic
- create a getter method that correctly returns the locking status
function _isLocked() internal view {
return !_is_locked || now > unlock_date;
}
- make
modifier onlyUnlocked()
use the newly created getter (_isLocked()
) - make
Vega_Token.is_tradeable()
use the newly created getter (_isLocked()
) _unlock()
should raise an errorcondition when called on an already unlocked contract- it could make sense to emit a “contract hast been unlocked” event for auditing purposes
7 Tool-Based Analysis
Several tools were used to perform automated analysis of the reviewed contracts. These issues were reviewed by the audit team, and relevant issues are listed in the Issue Details section.
7.1 MythX
MythX is a security analysis API for Ethereum smart contracts. It performs multiple types of analysis, including fuzzing and symbolic execution, to detect many common vulnerability types. The tool was used for automated vulnerability discovery for all audited contracts and libraries. More details on MythX can be found at mythx.io.
The output of a MythX Full Mode analysis was reviewed by the audit team and no relevant issues were raised as part of the process.
7.2 Ethlint
Ethlint is an open source project for linting Solidity code. Only security-related issues were reviewed by the audit team.
Below is the raw output of the Ethlint vulnerability scan:
Solium version 1.2.5
contracts/Address.sol
22:8 warning Line contains trailing whitespace no-trailing-whitespace
29:8 error Avoid using Inline Assembly. security/no-inline-assembly
contracts/ERC20Lockable.sol
58:8 warning Provide an error message for require() error-reason
58:31 warning Avoid using 'now' (alias to 'block.timestamp'). security/no-block-members
66:8 warning Provide an error message for require() error-reason
66:16 warning Avoid using 'now' (alias to 'block.timestamp'). security/no-block-members
contracts/ERC20StaticSupply.sol
15:4 warning Line exceeds the limit of 145 characters max-len
contracts/SafeERC20.sol
33:16 error Only use indent of 12 spaces. indentation
67:65 warning Avoid using low-level function 'call'. security/no-low-level-calls
contracts/Vega_Token.sol
9:1 warning Line contains trailing whitespace no-trailing-whitespace
7.3 Surya
Surya is a utility tool for smart contract systems. It provides a number of visual outputs and information about the structure of smart contracts. It also supports querying the function call graph in multiple ways to aid in the manual inspection and control flow analysis of contracts.
Below is a complete list of functions with their visibility and modifiers:
Sūrya’s Description Report
Files Description Table
File Name | SHA-1 Hash |
---|---|
contracts/Vega_Token.sol | b92b3c54b2f47a88fa9e84534046b462dbaee9aa |
contracts/Address.sol | 1213b0f150dd5e3f694c3721c44cb5cc3202b743 |
contracts/ERC20Detailed.sol | 7e4d00c462120565201f28361b29201d1bfe0a34 |
contracts/IERC20.sol | 72c15b6a16b7dc92e69ff97ccfe1958d9948e200 |
contracts/ERC20Lockable.sol | 377447995444beee2b3c5342bfa9b1bbc1d08356 |
contracts/SafeMath.sol | c8bda5eb19c16d34bc48bf115229a9b967feb6ef |
contracts/ERC20StaticSupply.sol | bf3e66af74470eed08d0e0f82b9a98705a745c7c |
contracts/Ownable.sol | 12ec51ec8a3b4eed6326434fd0f5926b40602778 |
contracts/Roles.sol | 2c85acf184ae36f96ebafd8f6e26232ea459a711 |
contracts/SafeERC20.sol | ebd65ea9a0cdcb29bbbbf651a1076d51be031443 |
Contracts Description Table
Contract | Type | Bases | ||
---|---|---|---|---|
└ | Function Name | Visibility | Mutability | Modifiers |
Vega_Token | Implementation | Ownable, ERC20StaticSupply | ||
└ | Public ❗️ | 🛑 | ERC20StaticSupply | |
└ | unlock_token | Public ❗️ | 🛑 | onlyOwner |
└ | is_tradable | Public ❗️ | NO❗️ | |
Address | Library | |||
└ | isContract | Internal 🔒 | ||
└ | toPayable | Internal 🔒 | ||
ERC20Detailed | Implementation | IERC20 | ||
└ | Public ❗️ | 🛑 | NO❗️ | |
└ | name | Public ❗️ | NO❗️ | |
└ | symbol | Public ❗️ | NO❗️ | |
└ | decimals | Public ❗️ | NO❗️ | |
IERC20 | Interface | |||
└ | totalSupply | External ❗️ | NO❗️ | |
└ | balanceOf | External ❗️ | NO❗️ | |
└ | transfer | External ❗️ | 🛑 | NO❗️ |
└ | allowance | External ❗️ | NO❗️ | |
└ | approve | External ❗️ | 🛑 | NO❗️ |
└ | transferFrom | External ❗️ | 🛑 | NO❗️ |
ERC20Lockable | Implementation | IERC20 | ||
└ | _unlock | Internal 🔒 | 🛑 | |
└ | totalSupply | Public ❗️ | NO❗️ | |
└ | balanceOf | Public ❗️ | NO❗️ | |
└ | transfer | Public ❗️ | 🛑 | onlyUnlocked |
└ | allowance | Public ❗️ | NO❗️ | |
└ | approve | Public ❗️ | 🛑 | NO❗️ |
└ | transferFrom | Public ❗️ | 🛑 | onlyUnlocked |
└ | increaseAllowance | Public ❗️ | 🛑 | NO❗️ |
└ | decreaseAllowance | Public ❗️ | 🛑 | NO❗️ |
└ | _transfer | Internal 🔒 | 🛑 | |
└ | _mint | Internal 🔒 | 🛑 | |
└ | _burn | Internal 🔒 | 🛑 | |
└ | _approve | Internal 🔒 | 🛑 | |
└ | _burnFrom | Internal 🔒 | 🛑 | |
SafeMath | Library | |||
└ | add | Internal 🔒 | ||
└ | sub | Internal 🔒 | ||
└ | sub | Internal 🔒 | ||
└ | mul | Internal 🔒 | ||
└ | div | Internal 🔒 | ||
└ | div | Internal 🔒 | ||
└ | mod | Internal 🔒 | ||
└ | mod | Internal 🔒 | ||
ERC20StaticSupply | Implementation | ERC20Detailed, Ownable, ERC20Lockable | ||
└ | Public ❗️ | 🛑 | ERC20Detailed | |
└ | issue | Public ❗️ | 🛑 | onlyOwner |
Ownable | Implementation | |||
└ | Internal 🔒 | 🛑 | ||
└ | owner | Public ❗️ | NO❗️ | |
└ | isOwner | Public ❗️ | NO❗️ | |
└ | renounceOwnership | Public ❗️ | 🛑 | onlyOwner |
└ | transferOwnership | Public ❗️ | 🛑 | onlyOwner |
└ | _transferOwnership | Internal 🔒 | 🛑 | |
Roles | Library | |||
└ | add | Internal 🔒 | 🛑 | |
└ | remove | Internal 🔒 | 🛑 | |
└ | has | Internal 🔒 | ||
SafeERC20 | Library | |||
└ | safeTransfer | Internal 🔒 | 🛑 | |
└ | safeTransferFrom | Internal 🔒 | 🛑 | |
└ | safeApprove | Internal 🔒 | 🛑 | |
└ | safeIncreaseAllowance | Internal 🔒 | 🛑 | |
└ | safeDecreaseAllowance | Internal 🔒 | 🛑 | |
└ | callOptionalReturn | Private 🔐 | 🛑 |
Legend
Symbol | Meaning |
---|---|
🛑 | Function can modify state |
💵 | Function is payable |
Appendix 1 - Disclosure
ConsenSys Diligence (“CD”) typically receives compensation from one or more clients (the “Clients”) for performing the analysis contained in these reports (the “Reports”). The Reports may be distributed through other means, including via ConsenSys publications and other distributions.
The Reports are not an endorsement or indictment of any particular project or team, and the Reports do not guarantee the security of any particular project. This Report does not consider, and should not be interpreted as considering or having any bearing on, the potential economics of a token, token sale or any other product, service or other asset. Cryptographic tokens are emergent technologies and carry with them high levels of technical risk and uncertainty. No Report provides any warranty or representation to any Third-Party in any respect, including regarding the bugfree nature of code, the business model or proprietors of any such business model, and the legal compliance of any such business. No third party should rely on the Reports in any way, including for the purpose of making any decisions to buy or sell any token, product, service or other asset. Specifically, for the avoidance of doubt, this Report does not constitute investment advice, is not intended to be relied upon as investment advice, is not an endorsement of this project or team, and it is not a guarantee as to the absolute security of the project. CD owes no duty to any Third-Party by virtue of publishing these Reports.
PURPOSE OF REPORTS The Reports and the analysis described therein are created solely for Clients and published with their consent. The scope of our review is limited to a review of Solidity code and only the Solidity code we note as being within the scope of our review within this report. The Solidity language itself remains under development and is subject to unknown risks and flaws. The review does not extend to the compiler layer, or any other areas beyond Solidity that could present security risks. Cryptographic tokens are emergent technologies and carry with them high levels of technical risk and uncertainty.
CD makes the Reports available to parties other than the Clients (i.e., “third parties”) – on its website. CD hopes that by making these analyses publicly available, it can help the blockchain ecosystem develop technical best practices in this rapidly evolving area of innovation.
LINKS TO OTHER WEB SITES FROM THIS WEB SITE You may, through hypertext or other computer links, gain access to web sites operated by persons other than ConsenSys and CD. Such hyperlinks are provided for your reference and convenience only, and are the exclusive responsibility of such web sites’ owners. You agree that ConsenSys and CD are not responsible for the content or operation of such Web sites, and that ConsenSys and CD 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 ConsenSys and CD endorses the content on that Web site or the operator or operations 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 Reports. ConsenSys and CD assumes no responsibility for the use of third party software on the Web Site and shall have no liability whatsoever to any person or entity for the accuracy or completeness of any outcome generated by such software.
TIMELINESS OF CONTENT The content contained in the Reports is current as of the date appearing on the Report and is subject to change without notice. Unless indicated otherwise, by ConsenSys and CD.