ERC20
ERC20 Protocol is one of the most commonly used token standards. The ERC20 protocol defines the basic functionality and standardized interfaces for token contracts. We can divide the ERC20 protocol into three parts:
Basic metadata, including name, symbol, and decimals. The focus of auditing this part is on decimals, ensuring that the decimal setting is reasonable.
Basic operations, including total supply and balance query, token transfer, and authorization. The key point of auditing this part is to verify whether the query interface correctly handles boundary and exceptional cases, to prevent attackers from manipulating the token supply and balance through special inputs. It also involves checking for vulnerabilities that could lead to abnormal transfers or financial losses, such as reentrancy attacks and overflow vulnerabilities. It is important to validate the correct implementation of the authorization function and ensure proper verification and validation of authorization operations.
Token issuance business, where token minting and burning are implemented according to the issuance plan controlled by the owner. The focus of auditing this part is to verify the correctness of the issuance plan and token issuance logic, and to identify vulnerabilities related to unauthorized operations, such as failure to properly verify the identity of operators or implement proper permission controls.
There is also a special type of ERC20 token called Double-Entry Point Token. In addition to the token contract, there is another entry point contract that provides additional functionality and interaction methods. This design enhances the flexibility and extensibility of the token.
The following provides case explanations for common and significantly harmful vulnerabilities found in standard ERC20 token contracts and Double-Entry Point Token contracts.
Numerics Vulnerability in Decimals
Vulnerability Category: Numerics
The main functionality of the invest function is to transfer a specified amount of collateral to a designated strategy address and record the corresponding investment amount and collateral token information. However, this function does not check the decimal places of the token. This means that users can invest using tokens with different decimal places, which can result in accounting errors and potential financial losses.
Suggestion: Adding a new require statement to check if the investment token has the same number of decimal places as the first collateral token. If the condition is not met, an exception will be thrown, preventing the investment operation from proceeding. This ensures that only tokens with the same decimal places can be invested in the same strategy, thereby avoiding accounting errors and potential financial losses.
Access Control Vulnerability in Mint
Vulnerability Category: Access Control
The mint function has an improper access control configuration. The visibility of the mint function is set to public and does not have the onlyOwner modifier. This means that anyone can call the mint function, which in turn calls the _mint function to mint tokens.
The _mint function is an internal function and can only be called within the contract. It is used to mint a specified amount of tokens for the account address and update the relevant account and supply information. The constructor calls the internal function _mint to generate a specified quantity of tokens for a specified account. This prevents anyone from arbitrarily minting tokens, thus protecting the token's supply and maintaining its value stability.
However, the mint function can be called by anyone to mint tokens, which may lead to malicious users abusing this functionality and generating an unlimited number of tokens.
Suggestion: Add an access control mechanism where the mint() function requires onlyOwner verification, meaning that only the owner address can mint tokens.
Double Spending in Double-Entry Point Tokens
Issue: Double Spending
The following code implements the asset registration feature in the Reserve Protocol. This feature allows users to register any ERC20 token or tokens with double-entry point attributes as assets in an asset bucket. In this function, before registering an asset, the token address is checked for duplicates, and if it does not exist in the asset bucket erc20s, it is registered. As a result, there is a possibility that the addresses of two double-entry point tokens are successfully registered.
The following code implements the token issuance functionality. When a user wants to issue amtRToken, it loops through the information in the erc20s asset bucket. For double-entry point tokens, it performs two safeTransferFrom operations, resulting in the same transfer being executed twice, which leads to double spending. This behavior is not intended or expected.
Suggestion: To prevent double spending issues with double-entry point tokens, additional checks and handling can be implemented during asset registration. Within the _registerIgnoringCollisions function, when registering an asset, check if a double-entry point token has already been registered. If it has, unregister the old asset and register the new one, ensuring that each address is only registered once.
Last updated