美链(BEC)漏洞反思

in #bec6 years ago

问题

昨天,即4月22日,BEC合约 (是美链公司发布的token,于今年2月上线交易) 出现重大漏洞,现已暂停交易。

合约BUG

BEC的合约代码:Beauty Chain 美蜜 中出现严重bug,可以通过合约的批量转账的功能,无限复制token,参考文章一行代码蒸发了¥6,447,277,680 人民币!

详细问题,在上面的文章中已经讲得很详细,此处进行简单的总结:

  1. 合约代码中,有一个批量转账的功能,代码为:
  function batchTransfer(address[] _receivers, uint256 _value) public whenNotPaused returns (bool) {
    uint cnt = _receivers.length;
    uint256 amount = uint256(cnt) * _value;
    require(cnt > 0 && cnt <= 20);
    require(_value > 0 && balances[msg.sender] >= amount);

    balances[msg.sender] = balances[msg.sender].sub(amount);
    for (uint i = 0; i < cnt; i++) {
        balances[_receivers[i]] = balances[_receivers[i]].add(_value);
        Transfer(msg.sender, _receivers[i], _value);
    }
    return true;
  }

该功能能够接收一个地址列表,然后向每一份地址转账_value个token;

  1. 开发过C/C++的程序员,或者其他编译型语言的程序员应该知道,数值变量有溢出问题,所以,比如uint8的取值为0~255,一般的溢出算法下的话,255+1 == 0, 0-1 == 255。所以,在进行算术运算的时候,需要比较注意数值溢出问题;
  2. 上面合约中,uint256 amount = uint256(cnt) * _value; 这句没有进行溢出判断,
    也就是说,假设uint256最大值为MAX的话,如果转账数值 uint256(cnt) * _value == MAX+1,则amount=0,
    转账的时候,sender账户-amount,而接受者账户+_value,至此,就能够无限转账BEC了。

问题所在

合约的代码中,其实已经实现了安全的数学算法:

library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

  function sub(uint256 a, uint256 b) internal constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

但是,上面的乘法功能,并未使用自己实现的安全算法,从而导致bug出现;

反思

  • 智能合约的开发,是代码公开的方式,所以,开发时候一定要严格检查、测试;数据溢出、逻辑错误等等问题会导致严重的后果;
  • EOS的token开发,有官方的结构体asset,源代码在eos/contracts/eosiolib/asset.h,其中各种算数、逻辑运算都进行了安全判断。所以,在开发有关金融、数字货币等功能的时候,尽量使用该结构体;
Sort:  

Congratulations @redbutterfly! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You published your First Post
You got a First Vote

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do you like SteemitBoard's project? Then Vote for its witness and get one more award!

Coin Marketplace

STEEM 0.28
TRX 0.13
JST 0.032
BTC 61146.27
ETH 2924.49
USDT 1.00
SBD 3.58