Solidity语言中,变量支持的整数类型步长以 8 递增,支持从 uint8 到 uint256,以及 int8 到 int256
存储范围:
- uint8 : [0, 2^8-1]
- uint256 : [0, 2^256-1]
在智能合约中出现整数溢出的类型包括三种:
- 乘法溢出:(uint256)2 * 2^255 =(uint256) 0
- 加法溢出:(uint8)255 + 1 = (uint8)0
- 减法溢出:(uint8)0 - 1 =(uint8)255
漏洞场景:
乘法、加法、减法算术运算时,运算数值可控
漏洞防护:
使用 OpenZeppelin 维护的一套智能合约函数库中的SafeMath方法来处理算术逻辑
pragma solidity ^0.4.25;
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a / b;
return c;
}
function sub(uint256 a, uint256 b) internal constant returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
contract POC{
using SafeMath for uint256;
// 加法溢出
// 如果uint256类型的变量达到了它的最大值(2**256 - 1),如果在加上一个大于0的值便会变成0
function add_overflow() returns (uint256 _overflow) {
uint256 max = 2**256 - 1;
return max.add(1);
}
// 减法溢出
// 如果uint256类型的变量达到了它的最小值(0),如果在减去一个小于0的值便会变成
// 2**256-1(uin256类型的最大值)
function sub_underflow() returns (uint256 _underflow) {
uint256 min = 0;
return min.sub(1);
}
// 乘法溢出
// 如果uint256类型的变量超过了它的最大值(2**256 - 1),最后它的值就会回绕变成0
function mul_overflow() returns (uint256 _underflow) {
uint256 mul = 2**255;
return mul.mul(2);
}
}