什么是 SafeMath? SafeMath 是一个 Solidity 库,它提供了一组用于整数和固定点运算的安全函数。 为什么推荐使用 SafeMath? 安全性: SafeMath 在执行数学运算时会自动检查溢出和下溢问题。 如果检测到溢出或下溢,SafeMath 会抛出异常,阻止执行并回滚交易。 易于使用: SafeMath 提供了一套易于使用的函数,可以轻松地集成到的合约中。 使用 SafeMath 库可以减少开发人员手动编写溢出检查的负担。 标准化: SafeMath 已经被广泛接受为一个标准库,许多开发人员和审计员都熟悉它。 使用 SafeMath 可以提高代码的可读性和可维护性。 兼容性和可移植性: SafeMath 库是 Solidity 社区的一部分,因此它与其他使用 SafeMath 的项目兼容。
value.add(_value); // 调用SafeMath库的add函数 } } 在这个例子中,我们定义了一个名为SafeMath的库,它包含了一个add函数,用于安全地进行加法运算。 然后我们在MyContract合约中使用了SafeMath库,并调用了它的add函数。 部署 在Solidity中,库合约的部署与普通合约的部署过程基本相同。 以下是一个使用truffle部署库合约的例子: var SafeMath = artifacts.require(". /SafeMath.sol"); var MyContract = artifacts.require(". (SafeMath, MyContract); deployer.deploy(MyContract); }; 在这个例子中,我们首先部署了SafeMath库合约,然后将SafeMath库合约的地址链接到
尤达宝宝发布 0.8 新功能和如何使用 我们来看看两个大的新功能:集成的 SafeMath 和新的错误处理。 1. 集成 SafeMath ? SafeMath Meme 没错,你不需要再导入 Openzeppelin SafeMath[7]了。最重要的是,你不需要做任何事情就可以激活 Solidity 集成的 SafeMath。 则通过 unchecked形式包装语句来停用 SafeMath: contract Solidity08 { function test() external pure returns(uint256 目前可用的 Panic 有: 0x01: 使用 asset; 0x11: SafeMath 的溢出。 0x12: 除以 0。 0x21: 转换为不存在的枚举类型。 0x22: 存储字节数组编码错误。 移除任何 Openzeppelin SafeMath,你不再需要它了。 可能需要进行一些类型转换。 msg.sender和 tx.origin默认不属于 payable 类型。
//SPDX-License-Identifier:MIT pragma solidity^0.6.0; library SafeMath{ function add(uint256 a,uint256 b)internal pure returns(uint256){ uint256 c=a+b; require(c>=a,"SafeMath:addition overflow"); return c; } function sub(uint256 a,uint256 b)internal pure returns(uint256){ return sub(a,b,"SafeMath return c; } function div(uint256 a,uint256 b)internal pure returns(uint256){ return div(a,b,"SafeMath return c; } function mod(uint256 a,uint256 b)internal pure returns(uint256){ return mod(a,b,"SafeMath
'; contract Fallback is Ownable { //Fallback合约继承自Ownable合约 using SafeMath for uint256; mapping( '; contract Fallout is Ownable { using SafeMath for uint256; mapping (address => uint) allocations 猜硬币游戏 目标:连续猜对十次 pragma solidity ^0.4.18; import 'openzeppelin-solidity/contracts/math/SafeMath.sol'; /SafeMath.sol'; contract CoinFlip { using SafeMath for uint256; uint256 public consecutiveWins;// true : false; expFlip.flip(side); } } 这里也贴一下 SafeMath.sol //SafeMath.sol pragma solidity
*/ event Approval(address indexed owner, address indexed spender, uint256 value); } library SafeMath a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath / function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath = 0, "SafeMath: modulo by zero"); return a % b; } }
. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * */library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, 'SafeMath */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, 'SafeMath ); // There is no case in which this doesn't hold return c; }}contract NTCLock { using SafeMath
]、 allownce[]、 toitalBalance、 totalSupply 溢出成功不代表一定有危害 漏洞预防 有效的上下文校验 require()/assert()/revert() 使用SafeMath 直接调用SafeMath函数 using safeMath for uint256 SafeMath库 pragma solidity ^0.4.24; library SafeMath {
[]、 allownce[]、 toitalBalance、 totalSupply 溢出成功不代表一定有危害 漏洞预防 有效的上下文校验 require()/assert()/revert() 使用SafeMath 直接调用SafeMath函数 using safeMath for uint256 SafeMath库 pragma solidity ^0.4.24; library SafeMath {
3 合约开发&部署 3.1 智能合约编写 我们要编写两个合约,其中SafeMath.sol是一个算数运算防溢出的安全库,xyc.sol是一个ERC20智能合约。 3.1.1 SafeMath.sol pragma solidity ^0.6.0; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath /SafeMath.sol"; abstract contract ERC20 { function totalSupply() public virtual view returns (uint256
3 合约开发&部署 3.1 智能合约编写 我们要编写两个合约,其中SafeMath.sol是一个算数运算防溢出的安全库,xyc.sol是一个ERC20智能合约。 3.1.1 SafeMath.sol pragma solidity ^0.6.0; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath /SafeMath.sol"; abstract contract ERC20 { function totalSupply() public virtual view returns (uint256
可以看如上截图 除了amount的计算外, 其他的给用户转钱 都用了safeMath 的方法(sub,add) 那么 为啥就偏偏这一句没有用safeMath的方法呢。。。 这就要用写代码的人了。。。 啥是safeMath ? safeMath 是为了计算安全 而写的一个library 我们看看他干了啥? 我个人看法是 只要涉及到计算,一定要用safeMath 代码一定要测试! 代码一定要review! 必要时,要请专门做代码审计的公司来 测试代码 这件事后需要如何处理呢?
* `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. . */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath
这就是为什么如果用了 SafeMath 就会没问题,因为 SafeMath 会抛出错误,直接中断回滚 transferFrom 函数。
实际上对于这种整数溢出漏洞,最简单的方法是采用 SafeMath 数学计算库来避免。 有趣的是BEC智能合约代码中,其实其他的都使用了SafeMath, 而关键的uint256 amount = uint256(cnt) * _value却没有使用。 心痛程序员,也心痛韭菜。 这句代码改为uint256 amount = _value.mul(uint256(cnt));就可以防止溢出问题 所以在做加减乘除的时候请记得一定使用:SafeMath
// 定义一个库 SafeMath library SafeMath { function mul(uint a, uint b) internal pure returns ( Multiplication overflow"); return c; } } contract MyContract { using SafeMath value; function multiply(uint amount) public { value = value.mul(amount); // 使用SafeMath
防御措施 1、所有的数值运算操作全部采用SafeMath来实现 2、使用最新的编译器,最新版本编译器会自动检测是否存在类似的安全问题 ? issues/1760 https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol
第二个函数 0 - 1 = 115792089237316195423570985008687907853269984665640564039457584007913129639935 解决溢出问题使用SafeMath solidity ^0.4.24; //author: netkiller <netkiller@msn.com> //homepage: http://www.netkiller.cn library SafeMath { c = a + b; assert(c >= a); return c; } } contract NetkillerSafeMath { using SafeMath pure public returns (uint256){ uint256 result = a.div(b); return result; } } 测试 SafeMath
因为没用用safemath...导致任何人都能通过这一行(也就是 0- value) 0-value是不会报错的(当然如果用safemath的话,是会报错的。。。) 合约的问题 当然是做加减乘除的时候没有用safemath 逻辑还有一个问题 正常来说,应该需要加一个 判断,被授权的金额 不能大于 要发送的金额。。。
ERC20.sol"; import" openzeppelin/contracts/utils/Counters.sol"; import" openzeppelin/contracts/utils/SafeMath.sol contracts/token/ERC20/ERC20Interface.sol"; contract Exchange is ERC20Interface,Ownable,Counters{ using SafeMath