前言
- 關(guān)于智能合約solidity語(yǔ)法丈钙,請(qǐng)點(diǎn)擊參考資料
- 本文摘取的是的BNB合約源碼雏赦,如需查看源碼,可點(diǎn)擊[Code]
(https://etherscan.io/address/0xb8c77482e45f1f44de1745f52c74426c631bdd52#code)
淺談 BEC的合約漏洞
- 查閱BEC的智能合約代碼填大,BEC的合約漏洞是batchTransfer函數(shù)的數(shù)據(jù)溢出俏橘。BEC 直接使用普通的加減乘除符號(hào),缺少溢出判斷靴寂,這就造成數(shù)據(jù)溢出的隱患召耘。
uint256 amount = uint256(cnt) * _value;
如果cnt = 2, _value=2^255
,那么amount = 0
怎茫。因?yàn)橐绯龊螅?jì)算機(jī)取后面256
位(都是0
)蜜宪。
//合約地址:https://etherscan.io/address/0xc5d105e63711398af9bbff092d4b6769c82f793d#code
//合約代碼
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;
}
分析BNB 的 SafeMath源碼
乘法圃验,僅限內(nèi)部調(diào)用,返回
uint256
uint256 c = a * b;
容易溢出澳窑,比如a=2,b=2^255
乘積2^256
剛好溢出摊聋。結(jié)果取后面的256位(全為0),導(dǎo)致c=0
麻裁。- 所以使用
(a == 0 || c / a == b)
,驗(yàn)證結(jié)果的一致性
function safeMul(uint256 a, uint256 b) internal returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
除法色迂,僅限內(nèi)部調(diào)用歇僧,返回
uint256
assert(b > 0)
, 確保被除數(shù)不能為0
assert(a == b * c + a % b);
防止溢出锋拖,驗(yàn)證結(jié)果的一致性
function safeDiv(uint256 a, uint256 b) internal returns (uint256) {
assert(b > 0);
uint256 c = a / b;
assert(a == b * c + a % b);
return c;
}
減法,僅限內(nèi)部調(diào)用,返回
uint256
assert(b <= a)
因?yàn)榉祷刂敌枰?正數(shù)倔撞,所以此處判斷b
必須小于等于a
function safeSub(uint256 a, uint256 b) internal returns (uint256) {
assert(b <= a);
return a - b;
}
加法,僅限內(nèi)部調(diào)用鄙陡,返回 uint256
assert(c>=a && c>=b);
//驗(yàn)證結(jié)果: 兩個(gè)正數(shù)相加躏啰,和一定大于每個(gè)加數(shù)
function safeAdd(uint256 a, uint256 b) internal returns (uint256) {
uint256 c = a + b;
assert(c>=a && c>=b);
return c;
}
總結(jié):
不要直接使用簡(jiǎn)單的 "+-*/" ,盡量使用 library SafeMath 中的函數(shù)毫捣,避免整數(shù)溢出的隱患帝际。
關(guān)于計(jì)算機(jī)處理乘除法的原理
請(qǐng)參考:https://www.cnblogs.com/mamamia/p/7760341.html