V2 Factory 与 Pair
V2 Factory
V2 Factory 负责创建和索引 V2 交易对。每个唯一的代币对只有一个 V2 流动性池。
核心函数
getPair
返回两个代币的 Pair 合约地址,如果不存在则返回零地址。
function getPair(
address tokenA,
address tokenB
) external view returns (address pair);
代币顺序无关紧要 — getPair(A, B) 与 getPair(B, A) 返回相同结果。
allPairs
返回给定索引处的 Pair 地址。用于枚举遍历。
function allPairs(uint256 index) external view returns (address pair);
function allPairsLength() external view returns (uint256);
ABI
[
"function getPair(address tokenA, address tokenB) view returns (address pair)",
"function allPairs(uint256 index) view returns (address pair)",
"function allPairsLength() view returns (uint256)"
]
V2 Pair
每个 V2 Pair 是一个 ERC-20 合约(LP 代币),同时持有池的储备量并执行兑换。
核心函数
getReserves
返回当前的代币储备量和最后一个区块的时间戳。
function getReserves() external view returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
token0 始终是地址较小的代币。
token0 / token1
返回池中代币的地址。
function token0() external view returns (address);
function token1() external view returns (address);
totalSupply / balanceOf
用于 LP 代币记账的标准 ERC-20 函数。
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
ABI
[
"function getReserves() view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)",
"function token0() view returns (address)",
"function token1() view returns (address)",
"function totalSupply() view returns (uint256)",
"function balanceOf(address owner) view returns (uint256)",
"function approve(address spender, uint256 value) returns (bool)",
"function transfer(address to, uint256 value) returns (bool)"
]
示例:读取池状态
const FACTORY_ABI = [
"function getPair(address, address) view returns (address)"
];
const PAIR_ABI = [
"function getReserves() view returns (uint112, uint112, uint32)",
"function token0() view returns (address)",
"function token1() view returns (address)",
"function totalSupply() view returns (uint256)"
];
const factory = new ethers.Contract(V2_FACTORY, FACTORY_ABI, provider);
const pairAddress = await factory.getPair(tokenA, tokenB);
if (pairAddress === ethers.ZeroAddress) {
console.log("Pool does not exist");
} else {
const pair = new ethers.Contract(pairAddress, PAIR_ABI, provider);
const [reserve0, reserve1] = await pair.getReserves();
const token0 = await pair.token0();
console.log(`Reserve ${token0 === tokenA ? 'A' : 'B'}: ${reserve0}`);
console.log(`Reserve ${token0 === tokenA ? 'B' : 'A'}: ${reserve1}`);
}