场景简介
以太坊中的数字是会向上或向下溢出的,比如 uint8的范围是0~255,如果0 减去-1就会得到最大的数255。合约代码如下:
合约功能简介:为了演示,合约中的逻辑贼简单(丐版ERC20)。就是一个简单的token合约,transfer函数就是负责从A账户向B账户转移token。这个合约本来大家都没钱,但是还是能从一个没钱的账户转Token到另一个账户,而且转以后两个账户都有钱。测试代码及结果如下:
原因解析
攻击能成功的原因就是代码使用了不安全的减法操作,导致了 0减去一个正数后又得到一个正数(合约 line 8)。
解决方法
解决方法有很多,比较推荐的方法: 第一, 是 使用安全库 openzeppelin的 SafeMath, 里面的代码都是经过千锤百炼的。第二, 采用高版本的solidity 0.8以上,底层编译器因为帮你做了溢出 revert的操作。结合之前第一篇的可重入攻击,再次证明了,大家编写solidity 智能合约尽量用高版本的!!!因为solidity语言的开发者已经在底层做了很多防攻击逻辑。当然了,如果你足够自信,给你的代码加上 unchecked的关键字,那你的代码又开始裸奔了~