Blockchain Security Company BEOSIN: Summary of Token-level Security Issues

February 19 00:49 2022

Token-level security issues cannot be ignored in blockchain security. BEOSIN’s security technical team have summarized some token-level issues occurred in DEFI and categorized them into two types: the first is the token-level issues by themselves; the second is the issues that may arise in interactions between tokens and DEFI.

#A. Token-level issues

  1. Integer overflows

Why are integer overflows so important? The main reason is because they can cause huge losses once they occur. Before version 0.8.0, EVM did not have an overflow checking mechanism and needed to pay special attention to the integer overflow issue during numerical operations. After version 0.8.0, Solidity introduced its own overflow checking mechanism, which fundamentally avoids the integer overflow problem, but also note that when the unchecked keyword is used, the numerical operations involved are also not checked for overflow.

Integer overflow is generally divided into integer overflow and underflow. Integer overflow means that when the result of an operation is greater than the upper limit of the value specified by the uint data type, it will lead to overflow to the lower limit of the value to start recalculation (generally that is, 0).

For example, the value range of uint8 is 0-255, when a variable a of uint8 type is assigned to 260, it will overflow to 0+(260-256)=4, thus the value of a will become 4. Similarly, when a variable is assigned to a value smaller than 0, it will lead to underflow issue.For example, a variable b of uint8 type is assigned to b=0 – 5, then the value of b will not be -5 (uint8 type is unsigned integer, so there is no negative number), so the value of b will become 256-5=251.

The figure below shows the multiTransfer function of a token, which does not use SafeMath to perform an integer overflow check when accumulating the tokens array of the input parameters, giving an attacker the opportunity to construct an integer overflow attack. This will cause the value of totalTokensToTransfer to overflow to a smaller value and pass the balance check, transferring a huge amount of assets.

multiTtansfer function of Ammbr contract

Recommendation

It is recommended to introduce SafeMath to perform arithmetic on the data before version 0.8.0. When using unchecked in version 0.8.0 and above, it is recommended to use functions such as require to check for overflow.

2. Function Permission Errors

Function permission errors are usually caused by contract developers’ negligence. Many internal functions will directly change the contract storage data in the running process without checking (e.g., changing contract manager permissions, calling key contract parameters, etc.). If the visibility of such function is set to public or external, it will create a major security vulnerability. This issue occurred in October of this year with AVATerra Finance, which set the visibility modifier of the mint function mint to public, allowing any attacker could perform mint operations.

 

AvaterraToken contract codes

Recommendation

Do strict permission checks on sensitive functions such as minting and permission changes, and determine the visibility of such functions based on business logic.

3. Excessive authority

Administrators with excessive contractual authority can have uncontrollable amounts of user assets and unstable asset values. If the administrator has the authority to transfer and destroy the user’s balance at will, the user’s assets can be returned to zero at any time; if the administrator has the authority to mint unlimited coins as a function, such tokens can be issued in large quantities, making the token price depreciate rapidly.

The following figure shows the function that allows the administrator to destroy user tokens at will. Here the onlyRole modifier is used, and the burnFrom function is overridden to cause the tokens of the specified account to be destroyed at will.

burnFrom function with high permissions

Recommendation

Do a strict review on the scope of administrator’s permission, and pay attention to operations such as transferring users’ tokens and destroying users’ tokens in violation. It is recommended to remove these codes with potential issues to protect users’ property.

4. Self-additional issuance vulnerability

This vulnerability is a special logic vulnerability, a self-additional issuance vulnerability caused by multiple local variables set in the transfer function when users transfer money to themselves, resulting in variables overwriting each other.

A typical example of this vulnerability is the Troncrashcoin token, whose transfer function logic is as follows:

1. create new variables oldFromVal and oldToVal to store old balances; 2. create new variables newFromVal and newToVal to store new balances, i.e. oldFromVal+_value and oldToVal+_value; 3. assign newFromVal and newToVal to balances[_from] and balances[_to].

Once the _to address and _from address are the same, balances[_from] will be overwritten by the value of balances[_to], resulting in the previously reduced _value not working, thus creating the vulnerability of self-increasing _value but not reducing _value.

_transfer function of Troncrashcoin

Recommendation

After development, the project party needs to completely test whether the each function point is executed properly, and conduct a complete input test of all callable functions and their input parameters to verify if the business logic meets the requirements. For example, testing whether a series of special cases such as extreme values and self-transfer meet the logic.

5. Incoming parameters are not verified correctly

In the execution of the function, if the reasonableness of the incoming parameters is not verified, it may lead to the function not being executed as expected. For instance, if the permit function does not perform zero address verification and the corresponding tokens are destroyed by sending the tokens to the zero address, then the attacker can transfer the destroyed tokens in the zero address. Also for example, there will be a freeze function in some smart contracts, but when transferring tokens, only the source account is verified, while the transfer address is not verified, resulting in the transferred tokens cannot be withdrawn. Also note that the transferFrom needs to additionally verify the from address. There is a similar problem with blacklist verification.

 

Transfer function without validation of the forwarding address

Another example is the NaughtCoin question in the Ethernaut. Since the ERC20 only qualifies the transfer, not the transferfrom, the attacker can directly call approve and transferfrom through the standard ERC20 interface for token extraction.

 

NaughtCoin of Ethernaut

Recommendation

All functions called by the user are checked for the reasonableness of the parameters passed in. Avoid exceptions caused by unreasonable use of parameters. When using functions with restrictions, verify if the inappropriate parameters that passed in will bypass the restriction or that there are other similar functions that can be bypassed.

6. Developer Backdoors

Some administrators will ask someone to develop it for them during the development stage. In this case, if the developer leaves a backdoor inside the Token, then the Token with the backdoor will cause losses to both the project and the users once it comes online. For example, the following is the backdoor left by token HJL in the minting function, resulting in 1% of additional tokens flowing into the address 0xfa every time the token is minted, resulting in the actual circulation of the token being greater than the displayed value.

mint function of the HJL token 

Recommendation

It is recommended to conduct several more audits before the tokens go live and to verify if the hash of the deployed tokens are consistent with the final audited version.

Media Contact
Company Name: Beosin
Contact Person: Donny
Email: Send Email
Country: China
Website: www.beosin.com