欢迎访问 内存溢出 —— 独立后端与系统工程技术博客

专注于分布式系统、Linux内核、数据库存储与后端工程实践

Solidity 整数溢出与精度损失:Unchecked 块与 SafeMath 迁移

发表于:|最后更新:|分类:区块链安全|阅读:1930 次

Solidity 0.8.0 之前,整数运算默认不检查溢出,uint256 加法回绕可导致代币余额凭空增加。0.8+ 默认内置溢出检查,但开发者使用 unchecked 块优化 Gas 时若逻辑不当,会重新引入溢出风险;此外乘除顺序不当会造成精度损失。

一、unchecked 块的安全边界与精度修复

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract SafeMathDemo {
    // 危险:unchecked 内做用户可控加法,可溢出回绕
    function unsafeAdd(uint256 a, uint256 b) external pure returns (uint256) {
        unchecked { return a + b; } // 若 a+b 溢出则回绕
    }

    // 安全:仅在已证明不会溢出的循环计数器上使用 unchecked
    function sumArray(uint256[] calldata arr) external pure returns (uint256 total) {
        for (uint256 i = 0; i < arr.length; ) {
            total += arr[i];
            unchecked { ++i; } // 仅自增,边界由循环条件保证
        }
    }

    // 精度修复:先乘后除,避免整数除法截断
    function proportional(uint256 amount, uint256 rate) external pure returns (uint256) {
        return (amount * rate) / 1e18; // 而非 amount * (rate / 1e18)
    }
}