【得得预警】应该重视ERC20智能合约引起的approve缺陷

SECBIT实验室
SECBIT实验室 机构得得号

Jun 16, 2018 聚焦智能合约安全审计和形式化验证。

摘要: 最近智能合约安全事件频发,从BEC到SMT,从HXG到FXE等,最近这几个智能合约出的问题,大多是由于整数溢出导致的。是不是应该在所有的地方都加上安全检查,确保我们的代码没有问题呢?

最近安比(SECBIT)实验室发现一个ERC20智能合约的approve缺陷,该缺陷将导致项目token在去中心化交易所中无法正常交易。

最近智能合约安全事件频发,从BEC到SMT,从HXG到FXE等,最近这几个智能合约出的问题,大多是由于整数溢出导致的。大家对整数溢出是不是都杯弓蛇影了?我们是不是应该在所有的地方都加上安全检查,确保我们的代码没有问题呢?

我们注意到在下面这段代码:

function approve(address _spender, uint _amount) returns (bool success) {
  // approval amount cannot exceed the balance
  require ( balances[msg.sender] >= _amount );
  // update allowed amount
  allowed[msg.sender][_spender] = _amount;
  // log event
  Approval(msg.sender, _spender, _amount);
  return true;
}
这是ERC20接口中的approve函数的一个实现,我们注意到,在函数最开始的地方有这样一行:

require ( balances[msg.sender] >= _amount );

approve的时候对当前余额进行检测,要求授权的_amount小于或等于当前余额。这样写实际上是没什么意义的,因为在后续操作能够根据正常逻辑产生和这个条件相违背的状态。比如approve给某个地址后,token的所有者又把token都转走。

这样写除了没有意义外,其实还会引起比较大的使用问题。

最近我们在和去中心化交易所DDEX合作审计该平台上的ERC20 token的智能合约,发现一个比较严重的问题。目前的去中心化交易所,很多都用到了ZRX protocol或者类似的协议。在ZRX的智能合约里,进行转账的时候,通过Exchange合约的fillOrder函数完成转账。

去中心化的交易所需要准备一个中间账户,由这个中间账户发起的交易,中间账户需要向该合约approve足够的allowance。而ZRX提供的合约并不提供approve过程,需要交易所提供的中间账户提前准备好这个approve工作。

然而如果这个中间账户并没有提前拥有交易的token,由于上面那条代码的检查条件,导致无法提前完成approve,这样的问题给去中心化交易所带来了较大的困扰。

在各种去中心化交易所中,甚至中心化的交易所中类似的情况并不少见。因此我们强烈推荐大家在写ERC20智能合约时不要这么写,不要画蛇添足的加上这样一个判断。

如果万一已经发布的ERC20 token合约已经这么写了,我们有什么办法吗?

当交易所遇到这种情况的时候,只能由项目方向交易所的中间账户打一笔足够大的token,才能保证能够approve成功,而且限制以后发生的交易额不能超过此数量的限制。

我们使用SECBIT的一个内部工具,对提供源码的22681个ERC20 Token智能合约进行了一次扫描,发现了21个智能合约存在此问题,其中有3个合约的交易量较大。涉及的Token包括:

IDH

GZR

ADE

SAINT

BULB

ZZZ

KTM

ETI-P

ZORRO01

ZORRO02

现在去中心化交易所将越来越多,为了不影响项目token未来的交易的流动性,我们建议各token仔细检查合约是否存在该问题,如果可能,尽早进行修正。

链得得仅提供相关信息展示,不构成任何投资建议
本文系作者 SECBIT实验室 授权链得得发表,并经链得得编辑,转载请注明出处、作者和本文链接

更多精彩内容,关注链得得微信号(ID:ChainDD),或者下载链得得App

分享到:

相关推荐

    评论(0

    Oh! no

    您是否确认要删除该条评论吗?

    分享到微信