How to pass the most trusted cryptocurrency platform’s security guidelines for ERC-20 tokens
By Nadir Akhtar
TL;DR: The ERC-20 standard has become a popular way to create digital assets and assign protocol voting rights on the Ethereum blockchain. When evaluating an ERC-20 token for listing, Coinbase performs a security assessment looking primarily for these four qualities:
- Verified source code
- Industry-standard library use
- Limited scope for privileged roles
- Simple, modular design
To safeguard users, Coinbase performs a thorough security review of each token before it can be listed. One of the most commonly requested token categories is an Ethereum smart contract standard known as an “ERC-20.”
You might be asking yourself, “How complicated can these tokens really get?” Spoiler alert: very. Though the ERC-20 standard is fairly simple, the diversity of ERC-20 implementations is remarkable, from simple individual contracts to entire ecosystems.
Below, we outline a set of security guidelines that we recommend for all ERC-20 tokens. These qualities give token holders confidence in ownership of their token and make exchanges such as Coinbase more likely to list that token. If these best practices are not followed, Coinbase may be unable to list your token or your listing may be delayed.
These qualities are fundamental to any secure smart contract project:
Verified Source Code
This is the most important step to getting a token listed. Without access to source code, an auditor or security engineer cannot easily analyze the token’s behavior, precluding high confidence reviews. Verifying code, a low effort action for an asset issuer, is the highest leverage step towards getting a token listed.
To effectively verify the token’s code:
- Upload the source code for all smart contracts to a reliable platform (for example, Etherscan).
- Add the code to an easily shareable repository, such as on GitHub, especially if it is not yet deployed.
- If the token is upgradable, use distinct releases to communicate the state of the token at each upgrade.
Industry-Standard Library Use
Similar to the adage of “don’t roll your own crypto,” avoid writing smart contract code from scratch as much as possible. A single developer or team may, regardless of experience, miss a crucial detail, compromising the integrity of the token. In comparison, popular and well-vetted open source smart contract standards are rigorously scrutinized and tested, making them the most secure known implementations.
Rather than building a token from scratch:
- Use popular and well-vetted standards whenever possible, such as OpenZeppelin’s vast repository of smart contracts.
- If implementing a special feature, such as off-chain signing or transaction hooks, use EIPs as guidance.
Limited Scope for Privileged Roles
Tokens often have privileged roles, also known as superusers, often termed “owner,” “admin,” or “controller.” In some smart contracts, these roles can wield significant power, such as pausing transactions, modifying balances, or completely changing the token’s logic. Superuser privileges threaten our ability to safely custody customers’ assets, diminishing the likelihood of listing the token on Coinbase.
To limit privileged roles:
- Do not allow any roles to freeze, burn, or otherwise modify user funds without permission.
- If feasible, use an upgrade pattern where the user must agree to token upgrades rather than allowing the privileged role to unilaterally change the contract’s functionality.
- If unable to do the above, provide detailed policies and procedures for quorum-based key management and use, especially for actions that impact user balances. Ideally, keys would be held by a qualified custodian that can certify that the quorum is met before the role is able to take action.
Simple, Modular Design
Our favorite tokens to evaluate from a security perspective are the boring ones: they come with no surprises. Though complex protocols may enable advanced features for tokens, the token itself need not be complicated. “Simple” refers to reducing the number of components composing a token project, and “modular” refers to separating logic and responsibilities between contracts.
To lessen the token’s complexity, thus minimizing possibility of failure:
- Keep token-related functions minimal by separating the token contract from the rest of the protocol.
- Reduce or eliminate external token dependencies.
- Prefer to use fewer contracts to implement the token.
These qualities are especially important for complex tokens that make substantially new programming or architectural decisions:
Smart contract development is laced with subtleties, and failures can cost millions of dollars. An external audit from a reputable security firm, looking for both smart contract vulnerabilities and business logic flaws, can uncover critical issues and increase confidence in the correctness of the token.
To ensure your token is properly examined for vulnerabilities:
- Request an audit from a reputable auditing firm, such as Trail of Bits, OpenZeppelin, or ConsenSys Diligence, focused on ensuring correct token balances and inspecting the most complex portions of the project.
- Use bug bounties to encourage smart contract security experts from around the world to review the token.
Well-organized and up-to-date documentation accurately describing a project in thorough detail is every engineer’s dream. Without such documentation, reviewers may be forced to spend excruciating time deciphering the project’s intent and structure.
To ease the lives of any onboarding developer or security engineer, ensure the availability of documentation which covers:
- The token’s purpose
- The project’s architecture and dependencies
- Superuser roles which affect the token’s behavior or user funds
- Security controls used to manage superuser keys and roles
- Use NatSpec to add documentation to the code as much as possible.
- If the documentation is out of date or the project is under rapid development, clearly indicate this to prevent misunderstandings.
Recent Solidity Version
Solidity, designed for the EVM, regularly evolves not only to empower developers but to defend smart contracts from vulnerabilities by default. The language builds in protections to prevent developers from accidentally making their smart contracts prone to attack; one such improvement with v0.5.0 was requiring explicit function visibility rather than allowing anyone to call a function by default.
Up-to-date Solidity versions come with an added benefit: popular tools for automated analysis, such as static analysis and formal verification tools, do not work as well (if at all) with older versions of Solidity.
To be as up to date as possible:
- Use the most recent stable version of Solidity available, using interfaces to interact with contracts of older versions.
- Rather than using a “floating” Solidity version, pin all contracts to a specific version to prevent unexpected results when compiling with a different version (with the exception of libraries).
Tokens, especially ones with complexity, should come with a comprehensive set of tests with significant coverage (aspiring for 100%), from unit tests to end-to-end tests. Tests not only catch bugs early but also implicitly describe a token’s expected behavior, a helpful complement to thorough documentation.
To ensure your token is well-tested:
- Write unit tests for each newly written function to test basic properties (e.g. a user cannot transfer more than their balance).
- Have end-to-end tests that go through important flows to ensure that the project behaves as expected, possibly catching severe bugs.
- Deploy the project to a testnet to test vital smart contract functionality and to catch any strange or unexpected issues (such as gas limits) before deploying to mainnet.
- Run automated analysis tools such as Slither, Echidna, and Mythril to discover well-known issues automatically. Consider consulting Certora to perform formal verification of important invariants for your token.
Although anyone can create a boilerplate ERC-20 token with relative ease, implementations can vary greatly in complexity and security. By developing tokens with these security best practices in mind, the path towards building an open financial system becomes much safer. At Coinbase, we look forward to embracing new technology and listing innovative projects on our platform and hope this guidance will be useful both to developers and the community at large.
This website contains links to third-party websites or other content for information purposes only (“Third-Party Sites”). The Third-Party Sites are not under the control of Coinbase, Inc., and its affiliates (“Coinbase”), and Coinbase is not responsible for the content of any Third-Party Site, including without limitation any link contained in a Third-Party Site, or any changes or updates to a Third-Party Site. Coinbase is not responsible for webcasting or any other form of transmission received from any Third-Party Site. Coinbase is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement, approval or recommendation by Coinbase of the site or any association with its operators.
Implementing Coinbase’s security guidelines does not guarantee an asset to be listed on Coinbase. Coinbase evaluates prospective assets against our Digital Asset Framework to assess factors like security, compliance, and the project’s alignment with our mission of creating an open financial system for the world. To apply for listing, fill out an application here.
Coinbase does not endorse or promote any of the projects or cryptocurrencies mentioned in this blogpost. Any descriptions of functionality and services provided are for information only. Coinbase is not responsible for any loss of funds or other damages caused as a result of using any of the projects described above.
Coinbase Ventures is an investor in Etherscan and Certora. Please see here for more information.
All images provided herein are by Coinbase.