SWC-134/硬编码gas用量的消息调用
transfer()和send()函数会转发固定的2300 gas。从历史上看,通常建议使用这些功能进行价值转移, 以防止重入攻击。但是,EVM指令的gas成本在硬分叉期间可能会发生重大变化,这可能会破坏已经部署 的对gas成本做出固定假设的合约系统。例如。由于SLOAD指令的成本增加,EIP 1884破坏了几个现有的 智能合约。
CWE漏洞分类
整改方案
在执行调用时,请避免使用transfer()和send()并且不要以其他方式指定固定的gas量。 使用.call.value(...)("")代替。使用checks-effects-interactions模式和/或可重入锁来 防止重入攻击。
参考文献
示例合约
hardcoded_gas_limits.sol
/*
* @author: Bernhard Mueller (ConsenSys / MythX)
*/
pragma solidity 0.6.4;
interface ICallable {
function callMe() external;
}
contract HardcodedNotGood {
address payable _callable = 0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa;
ICallable callable = ICallable(_callable);
constructor() public payable {
}
function doTransfer(uint256 amount) public {
_callable.transfer(amount);
}
function doSend(uint256 amount) public {
_callable.send(amount);
}
function callLowLevel() public {
_callable.call.value(0).gas(10000)("");
}
function callWithArgs() public {
callable.callMe{gas: 10000}();
}
}
hardcoded_gas_limits.yaml
description: Hardcoded gas limit
issues:
- id: SWC-134
count: 4
locations:
- bytecode_offsets: {}
line_numbers:
hardcoded_gas_limits.sol: [20]
- bytecode_offsets: {}
line_numbers:
hardcoded_gas_limits.sol: [24]
- bytecode_offsets: {}
line_numbers:
hardcoded_gas_limits.sol: [28]
- bytecode_offsets: {}
line_numbers:
hardcoded_gas_limits.sol: [32]