Original title: "Research Report 丨 Hardcore Analysis of the Principles of Smart Contract Vulnerabilities"
Original source : Binance Research Institute

Discussing the analysis of smart contract vulnerabilities Before, let's start with a basic example to understand what elements a smart contract will have.
● Variable: the balances in this example, in this contract is responsible for storing the deposit balance corresponding to the user address in the contract
< p>● Function: getBalance in this example, when the user calls this function, it will return the user's deposit balance in the contract
< br>
● Receive function: Receive in this example, which is a built-in function. It will be triggered when the contract receives the user’s incoming ETH and no other calls are made. In this example, when the receiving function is triggered, the state of the variable balances will be changed, and the msg.sender in the function represents the sender’s address of the transaction< /p>
● Fallback function: the fallback in this example, which is also a built-in function. Triggered when the user calls a function that does not exist, it can be understood as an exception handling function. In this example, when triggered, the transaction is rolled back, that is, the transaction is invalidated.
Understanding the causes of problems and summarizing the categories of problems can help We are better prepared. DASP (Decentralized Application Security Project) has collected ten kinds of smart contract vulnerabilities. Below we sort out the most common contract vulnerabilities and new attack modes.
1. Reentrancy vulnerability
Reentrancy vulnerability is the most famous smart contract vulnerability, As mentioned earlier, the DAO incident was also attacked by hackers for this reason. The principle of the vulnerability is to achieve the purpose of the attack by calling a function in a loop.

< /p>
Here is a simple withdrawal function that allows users to withdraw deposits according to the balance in the contract (userBalances) . It can be noticed that when the caller of this function is a smart contract, the withdrawal operation (msg.sender.call) will trigger the receive function of the smart contract and pass in the remaining gas. At this time, the balance recorded by the user in the original smart contract has not been reset to zero (userBalances[msg.sender] = 0), the attacker can call the withdrawBalance function again in the receive function, and through the vulnerability that the balance status has not been modified To achieve the purpose of repeated withdrawals until the gas is exhausted or the contract is emptied.

< /p>
Attack flow chart display
The defense method is also very simple, as long as the balance recorded in the smart contract is cleared first, and then the transfer action is performed, that is attacks can be avoided.

2. Integer overflow vulnerability
< br>
In Ethereum smart contracts, uint256 is a common integer type, which means that this variable can store integers ranging from 0 to 2^256 - 1, and the storage limit is about 78 bits The value of the number, you may think that this number is big enough, but it can still be used to achieve overflow, that is to say, when the value of a variable is 2^256 - 1, and the value of this variable is calculated again When adding one, its value will become 0 because it exceeds the storage limit. To avoid this vulnerability, we need to check the range of integers before integer operations, and immediately throw an exception when an overflow operation is detected.
3. Denial of service attack
Smart contract service interruption is a serious problem, Because the service interruption caused by some vulnerabilities is permanent and cannot be recovered. The attack principle includes: accidental execution of the SELFDESTRUCT instruction, access control authority error, gas limit reaching the upper limit of the block, which makes the contract unable to operate normally, and the use of exception throwing shown here, causing the contract to be permanently paralyzed.

< /p>
This is a simple example of an auction contract. The highest bidder can become the currentLeader, and record the bid as the highestBid, and return the previous bid amount to the previous bid leader. An attacker can deploy a smart contract, make the contract the currentLeader after normal bidding, and use the revert function in the receive function in the contract to throw an exception to invalidate the transaction. When other users want to bid, the transaction will fail because the contract cannot transfer money to the currentLeader (that is, the contract previously deployed by the attacker), and the function of the auction contract will be permanently invalidated, and the attacker will be able to win the auction bidding.

< /p>
Example of attacker contract
4. Tx origin vulnerability attack
User A calls the function inside contract B, and then calls contract C within the function. You can observe the difference between tx.origin and msg.sender.

< /p>

p>
Next, let’s take a look at the actual attack scenario. The sendTo function in the above smart contract must meet the condition that tx.origin and owner are equal before it will be executed, but the attacker can use the smart contract below As mentioned above, the difference between tx.origin and msg.sender cleverly bypasses the verification and triggers the sendTo function. The specific details are that when the attacker induces the owner of the contract in the above figure to trigger the fallback function of the contract in the figure below, if the attacking contract calls the sendTo function in the fallback function, the owner’s permission can be obtained to execute.

5. The return value of the external call is not properly processed
In smart contracts, when using low-level call function instructions, such as: address.call(), address.callcode(), address.delegatecall() and address.send(), etc., if the call fails No exception will be thrown, only the Boolean value of the call result will be returned, and the contract will continue to execute. If the return value of the call result is not checked, the smart contract may not work properly.

< /p>
We take a simple withdrawal function as an example. When a contract is used to call the withdraw function in the above figure, and if the contract cannot receive ETH transfers (for example, no payable is set), the caller will not be able to receive To ETH, but because the contract will continue to execute, the status record of the balances in the contract will be changed. The correction is written as follows:

6. Short address attack
This attack method mostly appears in ERC-20 (token standard agreement ) smart contract, we must first understand that when we call a function, we are actually parsing a bunch of ABI (Application Binary Interface) characters in the EVM (Ethereum Virtual Machine). Generally, ERC-20 standard tokens will implement the transfer function for transfer. When we call the transfer function, the call content of the transaction consists of 3 parts:
● 32 bytes, the address of Ethereum (the address is 20 bytes, the high bit zero padding), for example:
0000000000000000000000011223344556677889900aabbccddeeff11223344
● 32 bytes, representing the Number of tokens:
00000000000000000000000000000000000000000000000de0b6b3a7640000
If the attacker’s address is: 0x1234567890123456 789012345678901234567800 (mantissa is zero ), and the mantissa zero is intentionally discarded when calling transfer. If the content format is not checked in the contract, EVM will supplement it with 00 from the high bit of the third parameter (number of tokens) when reading, which will cause actual The number of tokens to be transferred is missing one byte, that is, shifted to the left by 8 bits, and the value is instantly enlarged by 256 times. The attacker successfully stole the tokens in the token contract.
7. Flash loan attack
Flash loan, as the name implies, is a fast loan, then this speed How fast? The official explanation is that the transaction of loan issuance and repayment must be completed in the same block on Ethereum. It can be said that flash loan is a subversive innovation with the help of blockchain technology. It has two main differences from traditional lending. One is that it does not require collateral, and the other is that it requires The repayment operation is performed in a transaction, so the party that lends the funds does not have to bear the risk of default, because only when the lending and repayment operations performed by the lender on the blockchain are indeed executed, the transaction only valid. That is to say, we can design a smart contract to lend funds, then perform some fund operations, and finally return the funds, and these operations will be completed in the same transaction. This brings hackers the opportunity to use flash loans to launch attacks, because it greatly reduces the attack cost of hackers. Most of the recent attacks in the DeFi field use flash loans, mainly by hackers through loans A huge amount of money is used to create a price difference on the agreement and arbitrage it, and then run away with improper profits after repayment. We understand the hacker's attack ideas from the bZx attack event:
1. The hacker borrowed from the decentralized digital asset derivative trading platform dYdX through flash loans 10,000 ETH
2. Use 5,000 ETH as collateral to lend 112 wBTC (Wrapped BTC, namely BTC cross-chain assets on Ethereum)
3. The remaining 5,000 ETHs went to the decentralized lending platform bZx to open a space for wBTC
4. Use the lent 112 wBTC to the decentralized exchange Uniswap to smash the market, causing the price of wBTC to drop rapidly
This series of operations allowed the hacker to make a lot of money by opening short positions on bZx, and then returned the 10,000 ETH lent by the flash loan, and obtained 350,000 worth of ETH in the process dollar earnings. The main reason for this attack is that the drastic changes in the price of Uniswap eventually led to the loss of assets. This should be a normal market behavior, but hackers maliciously manipulate the market to cause losses to the project party. The manipulation of the bZx contract has brought flash loans into the attention of more developers. On the one hand, many smart developers have developed brand-new decentralized financial applications, and at the same time, it has also made developers more vigilant against possible logical attacks.
The operation of the smart contract is passive, and all contract actions must be performed by The user initiates a transaction and calls the function in the contract to execute the action, and the contract execution is irreversible based on the characteristics of the blockchain, and when the contract is deployed on the blockchain, all data is open and transparent, even if the code is not Open source, you can also use the disassembly tool to push back the content of the contract. Therefore, developers need to be familiar with the principles of vulnerabilities and avoid them, and users should also understand contract security issues to protect their own rights and interests.
Welcome to join the official BlockBeats community:
Telegram Subscription Group: https://t.me/theblockbeats
Telegram Discussion Group: https://t.me/BlockBeats_App
Official Twitter Account: https://twitter.com/BlockBeatsAsia