4月25日上午各大媒体资讯报道“由于SMT出现异常交易,发现SMT的以太坊智能合约存在漏洞,各大交易所纷纷停止其充提币和交易”这一爆炸性消息。继前几天的BEC合约bug风波,又一个基于ERC-20的智能合约出现bug,各大社群和网站论坛开始了“为何代币被盗,合约bug频出“的讨论。因此,今日的币市行情也受到了巨大影响,这个bug到底是怎么回事呢?DRC技术部在此为大家解疑答惑啦~

SmartMesh(SMT)代币智能合约转币漏洞分析

1. 利用漏洞进行的非法交易是下面这个地址:

https://etherscan.io/tx/0x1abab4c8db9a30e703114528e31dee129a3a758f7f8abc3b6494aad3d304e43f

SMT智能合约地址:https://etherscan.io/address/0x55f93985431fc9304077687a35a1ba103dc1e081#code

2. 出现漏洞的智能合约的方法:

/*

* Proxy transfer SmartMesh token. When some users of the ethereum account has no ether,

* he or she can authorize the agent for broadcast transactions, and agents may charge agency fees

* @param _from

* @param _to

* @param _value

* @param feeSmt

* @param _v

* @param _r

* @param _s

*/

function transferProxy(address _from, address _to, uint256 _value, uint256 _feeSmt,

uint8 _v,bytes32 _r, bytes32 _s) public transferAllowed(_from) returns (bool){

if(balances[_from] < _feeSmt + _value) revert();

uint256 nonce = nonces[_from];

bytes32 h = keccak256(_from,_to,_value,_feeSmt,nonce);

if(_from != ecrecover(h,_v,_r,_s)) revert();

if(balances[_to] + _value < balances[_to]

|| balances[msg.sender] + _feeSmt < balances[msg.sender]) revert();

balances[_to] += _value;

Transfer(_from, _to, _value);

balances[msg.sender] += _feeSmt;

Transfer(_from, msg.sender, _feeSmt);

balances[_from] -= _value + _feeSmt;

nonces[_from] = nonce + 1;

return true;

}

这个函数是用来让某个account B代替另一个account A进行转账,并且支付给B一定的手续费(以SMT支付),因为B的账户会消耗一定的gas。

标黄色的代码是出漏洞的地方,转账的额度是_value,手续费是_feeSmt。

这行代码的本意是检查当前_from这个账户(即真正要转账的账户)的余额是否小于转账额度加上手续费之和,如果小于,交易就会回滚(revert()),停止进行。正常情况下,调用这个合约方法的用户提供的转账额+手续费是很大数字的时候,这个转账就会回滚,因为账户余额不足。

但是假如用另外两个数的时候,就会出现问题,例如:

_value = 8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff = (2^255 + 2^252 - 1)

_feeSmt = 7000000000000000000000000000000000000000000000000000000000000001 = (2^255 - 2^252 + 1)

由于他们是uint256的数据类型,这两个数字加起来将超过uint256的上限值,也就是2^256(2的256次方),超过上限值后,根据uint256这个数据类型的特点,这个值将会变为0,换句话说这时两个数字加起来得到的和是0,所以这步检查就通过了,也就是说这两个很大的数字得以继续进行后续的转账。最终_value进入了_to这个账户(在这笔交易中也就是_from自己),_feeSmt进入了msg.sender这个账户(也就是调用合约方法的这个账户)。

这两个数字转换成10进制分别是:

_value = 65,133,050,195,990,400,000,000,000,000,000,000,000,000,000,000,000,000,000,000,

_feeSmt = 50,659,039,041,325,800,000,000,000,000,000,000,000,000,000,000,000,000,000,000

也就是大家在截图中看到的那两个数字,非常惊人!

近期频发代币合约出现bug情况引起各项目方的重视,DRC社区作为尽调项目方,也一直关注合约bug情况,项目代码审计的调研也在DRC尽调范围之类,欢迎需要DRC参与尽调的项目方和个人在留言区留言~

DRC社区是一个分布式协同专业服务平台,连通项目方、投资者、社区成员和专业机构,提供尽职调查、项目评级、数字资产估值与定价等专业服务,致力于促进区块链行业的健康发展。

自2017年8月创建以来,DRC社区组织了30余场线上、线下活动,尽调、研究了20多个典型项目,累计3000余位社区成员参与。DRC在2018年1月12日在上海举办的“独角兽青年领袖峰会”上正式发布了《DRC区块链项目风险评级框架》。

欢迎各位关注DRC公众号“DRC金融科技资讯”,阅读社区活动成果产出;加入社区电报群,参与社区活动。