init
Some checks failed
CI / test (10.x, ubuntu-latest) (push) Has been cancelled
CI / test (12.x, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
2025-07-08 01:27:47 +08:00
parent ee547b1785
commit 3586e648b2
8 changed files with 517 additions and 44 deletions

View File

@ -8,26 +8,42 @@ import './interfaces/IERC20.sol';
import './interfaces/IUniswapV2Factory.sol';
import './interfaces/IUniswapV2Callee.sol';
/**
* @title UniswapV2Pair 交易对合约
* @notice 这是Uniswap V2协议的核心合约实现了自动做市商(AMM)机制
* @dev 继承自IUniswapV2Pair接口和UniswapV2ERC20合约实现流动性代币功能
*/
contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20 {
using SafeMath for uint;
using UQ112x112 for uint224;
// 最小流动性常量,防止除零错误和攻击
uint public constant MINIMUM_LIQUIDITY = 10**3;
// ERC20 transfer函数的选择器用于安全转账
bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));
// 工厂合约地址
address public factory;
// 交易对中的两个代币地址token0 < token1
address public token0;
address public token1;
uint112 private reserve0; // uses single storage slot, accessible via getReserves
uint112 private reserve1; // uses single storage slot, accessible via getReserves
uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves
// 储备量使用uint112节省gas三个变量共用一个存储槽
uint112 private reserve0; // token0的储备量
uint112 private reserve1; // token1的储备量
uint32 private blockTimestampLast; // 上次更新的区块时间戳
uint public price0CumulativeLast;
uint public price1CumulativeLast;
uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event
// 价格累积器,用于计算时间加权平均价格(TWAP)
uint public price0CumulativeLast; // token0相对于token1的累积价格
uint public price1CumulativeLast; // token1相对于token0的累积价格
uint public kLast; // 上次流动性事件后的k值 (reserve0 * reserve1)
// 重入锁状态
uint private unlocked = 1;
/**
* @dev 重入锁修饰符,防止重入攻击
*/
modifier lock() {
require(unlocked == 1, 'UniswapV2: LOCKED');
unlocked = 0;
@ -35,17 +51,30 @@ contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20 {
unlocked = 1;
}
/**
* @notice 获取当前储备量和最后更新时间
* @return _reserve0 token0的储备量
* @return _reserve1 token1的储备量
* @return _blockTimestampLast 最后更新的区块时间戳
*/
function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
_reserve0 = reserve0;
_reserve1 = reserve1;
_blockTimestampLast = blockTimestampLast;
}
/**
* @dev 安全转账函数,确保代币转账成功
* @param token 代币合约地址
* @param to 接收地址
* @param value 转账数量
*/
function _safeTransfer(address token, address to, uint value) private {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
}
// 事件定义
event Mint(address indexed sender, uint amount0, uint amount1);
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
event Swap(
@ -58,13 +87,20 @@ contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20 {
);
event Sync(uint112 reserve0, uint112 reserve1);
/**
* @dev 构造函数,设置工厂地址为部署者
*/
constructor() public {
factory = msg.sender;
}
// called once by the factory at time of deployment
/**
* @notice 初始化交易对,只能由工厂调用一次
* @param _token0 第一个代币地址
* @param _token1 第二个代币地址
*/
function initialize(address _token0, address _token1) external {
require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // sufficient check
require(msg.sender == factory, 'UniswapV2: FORBIDDEN');
token0 = _token0;
token1 = _token1;
}