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金融科技资讯”,阅读社区活动成果产出;加入社区电报群,参与社区活动。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.