function _update(address from, address to, uint256 amount) internal virtual { if (from == address(0)) { _totalSupply += amount; } else { uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { // Overflow not possible: amount <= fromBalance <= totalSupply. _balances[from] = fromBalance - amount; } }此处使用unchecked{}是因为确定了不会溢出,才使用吗?
时间: 2024-02-15 20:28:20 浏览: 78
是的,使用`unchecked`关键字是因为在这种情况下可以确定不会发生溢出。在这个例子中,`amount`的值已经被检查过,因此可以确定`fromBalance - amount`不会导致溢出。使用`unchecked`关键字可以防止编译器出现警告。但是需要注意的是,如果不确定是否会溢出,就不能使用`unchecked`关键字,否则可能会导致不可预测的结果。
相关问题
简化此代码// SPDX-License-Identifier: MIT pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; contract CSAMM { IERC20 immutable token0; IERC20 immutable token1; uint public reserve0; uint public reserve1; uint public totalSupply; mapping(address => uint) public balanceOf; constructor(address _token0, address _token1) { token0 = IERC20(_token0); token1 = IERC20(_token1); } function _mint(address _to, uint _amount) private { // 此处补全 balanceOf[_to]=_amount; totalSupply+=_amount; } function _burn(address _from, uint _amount) private { // 此处补全 require(balanceOf[_from]>=_amount, '_amount>balance'); balanceOf[_from]-=_amount; totalSupply-=_amount; } function swap( address _tokenIn, uint _amountIn ) external returns (uint amountOut) { // 此处补全 amountOut=_amountIn; if(IERC20(_tokenIn)==token0){ token0.transferFrom(msg.sender, address(this), _amountIn); token1.transfer(msg.sender, _amountIn); _update(_amountIn+reserve0, reserve1-_amountIn); }else{ token1.transferFrom(msg.sender, address(this), _amountIn); token0.transfer(msg.sender, _amountIn); _update(reserve0-_amountIn, reserve1+_amountIn); } return amountOut; } function addLiquidity( uint _amount0, uint _amount1 ) external returns (uint shares) { if(totalSupply==0){ shares=_amount0+_amount1; token0.transferFrom(msg.sender, address(this), _amount0); token1.transferFrom(msg.sender, address(this), _amount1); _mint(msg.sender,shares); }else{ token0.transferFrom(msg.sender, address(this), _amount0); token1.transferFrom(msg.sender, address(this), _amount1); shares=(_amount0+_amount1)*totalSupply/(reserve0+reserve1); _mint(msg.sender,shares); } _update(_amount0+reserve0, _amount1+reserve1); } function removeLiquidity(uint _shares) external returns (uint d0, uint d1) { // 此处补全 d0=reserve0*_shares/totalSupply; d1=reserve1*_shares/totalSupply; token0.transfer(msg.sender, d0); token1.transfer(msg.sender, d1); _burn(msg.sender, _shares); _update(reserve0-d0,reserve1-d1); } function _update(uint _res0, uint _res1) private { reserve0 = _res0; reserve1 = _res1; } }
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract CSAMM {
IERC20 immutable token0;
IERC20 immutable token1;
uint public reserve0;
uint public reserve1;
uint public totalSupply;
mapping(address => uint) public balanceOf;
constructor(address _token0, address _token1) {
token0 = IERC20(_token0);
token1 = IERC20(_token1);
}
function _mint(address _to, uint _amount) private {
balanceOf[_to] += _amount;
totalSupply += _amount;
}
function _burn(address _from, uint _amount) private {
require(balanceOf[_from] >= _amount, '_amount > balance');
balanceOf[_from] -= _amount;
totalSupply -= _amount;
}
function swap(address _tokenIn, uint _amountIn) external returns (uint amountOut) {
amountOut = _amountIn;
if (IERC20(_tokenIn) == token0) {
token0.transferFrom(msg.sender, address(this), _amountIn);
token1.transfer(msg.sender, _amountIn);
_update(_amountIn + reserve0, reserve1 - _amountIn);
} else {
token1.transferFrom(msg.sender, address(this), _amountIn);
token0.transfer(msg.sender, _amountIn);
_update(reserve0 - _amountIn, reserve1 + _amountIn);
}
return amountOut;
}
function addLiquidity(uint _amount0, uint _amount1) external returns (uint shares) {
if (totalSupply == 0) {
shares = _amount0 + _amount1;
token0.transferFrom(msg.sender, address(this), _amount0);
token1.transferFrom(msg.sender, address(this), _amount1);
_mint(msg.sender, shares);
} else {
token0.transferFrom(msg.sender, address(this), _amount0);
token1.transferFrom(msg.sender, address(this), _amount1);
shares = (_amount0 + _amount1) * totalSupply / (reserve0 + reserve1);
_mint(msg.sender, shares);
}
_update(_amount0 + reserve0, _amount1 + reserve1);
}
function removeLiquidity(uint _shares) external returns (uint d0, uint d1) {
d0 = reserve0 * _shares / totalSupply;
d1 = reserve1 * _shares / totalSupply;
token0.transfer(msg.sender, d0);
token1.transfer(msg.sender, d1);
_burn(msg.sender, _shares);
_update(reserve0 - d0, reserve1 - d1);
}
function _update(uint _res0, uint _res1) private {
reserve0 = _res0;
reserve1 = _res1;
}
}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract TransactionHistory { event Transaction(address indexed from, address indexed to, uint256 indexed amount); function getTransactionHistory(address account) public { uint256 count = 0; uint256 currentBlock = block.number; uint256 lastBlock = currentBlock - 10; while (count < 10 && currentBlock > lastBlock) { currentBlock--; bytes32 blockHash = blockhash(currentBlock); if (blockHash != bytes32(0)) { uint256 txCount = block.number - currentBlock; for (uint256 i = 0; i < txCount && count < 10; i++) { bytes32 txHash = blockhash(currentBlock + 1); (address from, address to, uint256 amount) = parseTransaction(txHash); if (account == from || account == to) { emit Transaction(from, to, amount); count++; } } } } } function parseTransaction (bytes32 txHash) private pure returns (address, address, uint256) { (address from, address to, uint256 amount) = abi.decode(abi.encodePacked(txHash), (address, address, uint256)); return (from, to, amount); } }
这是一个基于以太坊的智能合约,名为TransactionHistory。它记录了过去10个区块内涉及到指定账户的交易记录,并提供getTransactionHistory函数来获取这些交易记录。当有符合条件的交易时,会触发Transaction事件,将交易的发送方、接收方、金额等信息记录下来。私有函数parseTransaction用于解析交易的哈希值,获取其中的发送方、接收方、金额等信息。
阅读全文