Considerations on the preparation of smart contracts from the BEC "token evaporation" event

Source: Internet
Author: User
Tags assert mul

Yesterday, the circle of Friends was an article brush screen, the United States chain (BEC) smart contract loopholes cause the token value almost zero event caused by the entire blockchain technology circle of concern (attached to the original text), today, two seniors take us to understand some of the smart contract writing considerations. 1 Overflow and Underflow

The solidity can handle 256 digits up to 2256-1, so adding 1 to (2 256-1) will result in 0. Similarly, a minus 1 operation on unsigned type 0 will be obtained (2**256-1)

The test code is as follows:

pragma solidity 0.4.18;
Contract Overflowunderflow  {
          uint public  zero =  0;
          UINT public  max =  2**256  -  1;
          Zero would end up at 2 * * 256-1
          function underflow () public  {
                     zero-=  1;
          }
          function overflow ()  public  {
                     Max + =  1;
          }
}

Although they are equally dangerous, in smart contracts, the impact of underflow is even greater.

For example, account a holds x tokens, if he initiates an X + 1 tokens transaction, if the code does not verify, then account A's balance may occur underflow resulting in more balances.

Can introduce Safemath Library solution:

pragma solidity 0.4.18; Library Safemath {function Mul (uint256 A, uint256 b) Internal Pure Returns (uint256) {if (a
                 ==0) {return 0;
                 } UINT C = A * b;
                 ASSERT (C/A = = b);
          return C;
                   } function div (uint256 A, uint256 b) Internal Pure Returns (uint256) {uint256 c = A/b;
          return C;
                   } function sub (uint256 A, uint256 b) Internal Pure Returns (uint256) {assert (b <= a);
          return a-B;
                   } function Add (uint256 A, uint256 b) Internal Pure Returns (uint256) {uint256 c = a + B;
                   ASSERT (c >= a);
          return C;
          }} contract Overflowunderflow {using Safemath for uint;
          UINT public zero = 0;
      UINT Public max = 2 * * 256-1;    function underflow () public {zero = zero.sub (1);
          } function overflow () public {max = Max.add (1); }
}
2 Visibility and Delegatecall

Public functions can be called by any address

External functions can only be called from outside the contract

Private functions can only be called from within the contract

Internal functions allows calls from contracts and their sub-contracts

External functions consumes less gas than public because it uses calldata and public needs to replicate all parameters to memory. 3 delegatecall

Delegatecall is identical to a, message call apart from the fact, the code at the target address was executed in the con Text of the calling contract and Msg.sender and Msg.value do not change their values. This means, a contract can dynamically load code from a different address at runtime. Storage, current address and balance still refer to the calling contract, only the code was taken from the called address.

This feature can be used to build Library and modular code. But at the same time, it can also cause someone else to manipulate your code.

In the following example, the attacker invokes the PWN method to obtain the ownership of the contract.

pragma solidity 0.4.18;
Contract Delegate  {
          address public owner;
          function  Delegate (address _owner)  public  {
                   owner = _owner;
          }
          function PWN ()  public  {
                   owner = Msg.sender;
         }
}
Contract Deletagion  {
          address public owner;
          Delegate  Delegate;
          function  Delegation (address _delegateaddreses)  public  {
                   delegate  =  Delegate (_ delegateaddreses);
                   Owner = Msg.sender;
          }
          An attacker can call DELEGATE.PWN () in the context of delegation, this means that PWN () would modify the state of **dele gation** and not Delegate, the result was that the attacker takes unauthorized ownership of the contract.
          function  ()  public  {
                   if (Delegate.delegatecall (msg.data))  {this
                             ;
                    }
          }
}
4 reentrancy (Thedao hack)

When the call function is called in solidity, it forwards all gas that he receives if it has the value parameter.

In the code snippet, the call function is called before the sender's balance is actually reduced. Here is a vulnerability that has led to Thedao attacks.

function withdraw (UINT _amount)  public  {
      if (Balances[msg.sender]  >= _amount)  {
          if ( Msg.sender.call.value (_amount) ())  {
             _amount;
          }
          Balances[msg.sender]-  = amount;
      }
}

Quote from Reddit:

In simple words, it's like the bank teller doesn ' t change your balance until she had given you all the money you requested .  " Can I withdraw?  Wait, before that, can I withdraw? "
And so on.  The smart contracts as designed only check for the beginning once, and allow  themselves to be interrupted.

the original text: "A line of code evaporated ¥6,447,277,680 RMB." "

Source: Blockchain Development North Point

Author: crawler

Article reprinted from: CSDN

Author: genistein

Events

BEC Smart contract loophole burst, was exploited by hackers, instantly set off a large amount of BEC,60 billion in the instant zero.

And all this is because of a simple program Bug.

background

Today, someone in the group said, Beauty Chain Mei Honey code inside there is a bug, has been used to obtain the bug 57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000.7,.92,003,956,564,82e,+17 BEC.

The Operation record is 0xad89ff16fd1ebe3a0a7cf4ed282302c06626c1af33221ebe0d3a470aba4a660f (https://etherscan.io/tx/ 0XAD89FF16FD1EBE3A0A7CF4ED282302C06626C1AF33221EBE0D3A470ABA4A660F)

Let's take a look at how hackers are implemented.

We can see that the method of execution is batchtransfer.

What is this method for? (Send the same amount of tokens to the specified number of addresses).

The overall logic is

You pass a few addresses to me (receivers), and then pass on to me how many tokens you want to give to everyone (value);

Then you want to send the total amount = number of people sent * the amount sent;

Then ask your current balance to be greater than the total amount sent;

Then deduct the total amount you send;

The specified amount (value) is then sent to everyone inside the receivers.

Logically, there is no problem here, you want to send tokens to others, then your own balance must be greater than the total amount sent.

But this piece of code makes a stupid mistake.

Code Explanation

This method will pass two parameters:

_receivers

_value

The value of the _receivers is a list with two addresses:

0x0e823ffe018727585eaf5bc769fa80472f76c3d7

0xb4d30cac5124b46c2df0cf3e3e1be05f42119033

The value of the _value is:

8000000000000000000000000000000000000000000000000000000000000000

Let's look at the code again (see figure below):

Let us explain in one line:

UINT CNT = _receivers.length;

is to get _receivers inside there are several addresses, we can see from the above parameters only two address, so cnt=2, that is, to send tokens to two addresses.

uint256 amount = uint256 (CNT) * _VALUE;

uint256

The first uint256 (CNT) is to convert CNT into a uint256 type. So, what is the uint256 type. Or, what is the range of uint256 types?

The value range of the Uintx type is 0 to 2 x-1. That is, if it is uint8, then the value range of Uint8 is 0 to 2 of 8-1, that is, 0 to 255.

Then, the value range of the uint256 is:

0-2 of 256 square-1, 0 to 115792089237316195423570985008687907853269984665640564039457584007913129639935

Python calculates 2 of the 256-time square.

So what if the set value exceeds the value range? This situation is called overflow.

Give an example to illustrate:

Because the value of uint256 is too large, so use uint8 for example.

From the above we already know that the uint8 minimum is 0, the maximum is 255.

So when I was 255 + 1, what was the result? The result will become 0.

So when I was 255 + 2, what was the result? The result will become 1.

So when I was 0-1, what was the result? The result will become 255.

So when I was 0-2, what was the result? The result will become 254.

So, let's go back to the code above:

Amount = uint256 (CNT) * _value

Then amount = _value.

But at this point the _value is 16 binary, we turn it into 10 binary:

(Python 16-in-turn 10-binary)

can see _value = 57896044618658097711785492504343953926634992332820282019728792003956564819968

So amount = _value*2 = 115792089237316195423570985008687907853269984665640564039457584007913129639936

You can see the uint256 value range up to 115792089237316195423570985008687907853269984665640564039457584007913129639935 in the view above

At this point, Amout has exceeded the maximum, overflow is amount = 0

The next line of code require (CNT > 0 && cnt <= 20); The Require statement indicates that the statement must be correct, that is, CNT must be greater than 0 and less than or equal to 20

Our CNT equals 2, through.

Require (_value > 0 && balances[msg.sender] >= amount);

This sentence requires value greater than 0, our value is greater than 0, and the current user has a token balance greater than or equal to amount, because amount equals 0, so even if you do not have a token, is also satisfied.

Balances[msg.sender] = balances[msg.sender].sub (amount);

This sentence is the current user's balance-amount

The current amount is 0, so the current user token balance is not changed.

for (UINT i = 0; i < cnt; i++) {balances[_receivers[i]] = Balances[_receivers[i]].add (_value); Transfer (Msg.sender, _receivers[i], _value);}

This is the phrase that iterates through the addresses in the _receivers, doing the following for each address:

Balances[_receivers[i]] = Balances[_receivers[i]].add (_value); The balance of the address in _receivers = original Balance +value

So the balance of the address in the _receivers added 5.,789,604,461,865,81e,+76 tokens ...

Transfer (Msg.sender, _receivers[i], _value); This sentence only saves the record of the gift token.

Summary

A simple overflow vulnerability resulted in the value of the BEC tokens approaching 0.

So, does the developer consider the overflow problem?

In fact he considered, you can see the following screenshot:

In addition to the calculation of amount, the other to the user to transfer Money Safemath method (Sub,add).

Why, then, is this sentence not used Safemath method ...

This is going to ask the person who wrote the code ...

What is Safemath ?

Safemath is a library written for the purpose of computing security.

Let's see what it's doing. How to ensure the safety of computing.

function Mul (uint256 A, uint256 b) Internal constant Returns (uint256) {uint256 c = a * B;assert (a = = 0 | | c/a = = b); ret Urn C;}

such as the multiplication above. After calculating, he uses the Assert to verify that the result is correct.

If the above calculation amount, with mul words, then c/a = = B is to verify amount/cnt = = _value.

This sentence will carry out the error, because 0/cnt is not equal to _value.

So the program will error.

There will be no overflow ...

Well, there's a small problem, and the assert here require seems to be doing the same thing-all to verify that a statement is correct.

So what's the difference between the two?

If the assert is used, the gas limit of the program will be exhausted;

Require, however, consumes only the gas currently being executed.

Summary

So how do we avoid this problem?

My personal opinion is:

As long as the calculation is involved, be sure to use Safemath

The code must be tested.

The code must be review.

If necessary, ask a company that specializes in code audits to test the code.

How do you deal with this afterwards?

Currently, the method has been paused (fortunately can be paused) so I have read the article friends do not go to test ...

But what has happened.

My idea is that the snapshot before the vulnerability, the balance of all users, and then issue a new token, to the previous user to send the equivalent tokens ...

The source of this article: public number-New vision of Procedure

Author: two Seniors

The following is our community introduction, welcome all kinds of cooperation, exchange, study:)

Hiblock Blockchain community More activities Click "Read original" to view

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.