123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- import { MockUSDT__factory, ControlledERC20__factory } from "../typechain-types"
- import { IPancakeRouter02__factory, IPancakeFactory__factory, IPancakePair__factory } from "../typechain-types"
- import { config as dotenvConfig } from "dotenv"
- import { ethers } from "ethers"
- import fs from "fs"
- // BSC Testnet PancakeSwap V2 合约地址
- const PANCAKE_ROUTER_ADDRESS = "0xD99D1c33F9fC3444f8101754aBC46c52416550D1"
- const PANCAKE_FACTORY_ADDRESS = "0x6725F303b657a9451d8BA641348b6761A6CC7a17"
- const WBNB_ADDRESS = "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd"
- /**
- * @dev PancakeSwap信息查询脚本
- * 查询交易对的流动性、价格、用户余额等信息
- * 包含价格影响分析、LP代币信息、用户份额计算等功能
- */
- async function main() {
- dotenvConfig()
- const rpcUrl = process.env.BSC_TESTNET_RPC_URL
- const privateKey = process.env.PRIVATE_KEY
- if (!rpcUrl || !privateKey) {
- throw new Error("请在.env中配置BSC_TESTNET_RPC_URL和PRIVATE_KEY")
- }
- const provider = new ethers.JsonRpcProvider(rpcUrl)
- const wallet = new ethers.Wallet(privateKey, provider)
- console.log("📊 查询PancakeSwap信息...")
- console.log("📝 查询账户:", wallet.address)
- // 读取部署信息
- let deploymentInfo
- try {
- deploymentInfo = JSON.parse(fs.readFileSync("deployment-bsc-testnet.json", "utf8"))
- } catch (error) {
- console.error("❌ 无法读取部署信息文件,请先运行部署脚本")
- process.exit(1)
- }
- const mockUSDTAddress = deploymentInfo.contracts.mockUSDT
- const controlledERC20Address = deploymentInfo.contracts.controlledERC20
- console.log("📄 MockUSDT地址:", mockUSDTAddress)
- console.log("📄 ControlledERC20地址:", controlledERC20Address)
- // 获取合约实例
- const mockUSDT = MockUSDT__factory.connect(mockUSDTAddress, wallet)
- const controlledERC20 = ControlledERC20__factory.connect(controlledERC20Address, wallet)
- const pancakeRouter = IPancakeRouter02__factory.connect(PANCAKE_ROUTER_ADDRESS, wallet)
- const pancakeFactory = IPancakeFactory__factory.connect(PANCAKE_FACTORY_ADDRESS, wallet)
- // 检查交易对是否存在(如果不存在则提示先添加流动性)
- console.log("\n🔍 检查交易对...")
- const pairAddress = await pancakeFactory.getPair(mockUSDTAddress, controlledERC20Address)
- if (pairAddress === ethers.ZeroAddress) {
- console.log("❌ 交易对不存在,请先添加流动性")
- process.exit(1)
- }
- console.log("✅ 交易对地址:", pairAddress)
- // 获取交易对详细信息(储备量、代币地址等)
- const pair = IPancakePair__factory.connect(pairAddress, wallet)
- const [reserve0, reserve1, blockTimestampLast] = await pair.getReserves()
- const token0 = await pair.token0()
- const token1 = await pair.token1()
- // 确定哪个储备量对应哪个代币(PancakeSwap按地址排序)
- let mockUSDTReserve: bigint
- let controlledERC20Reserve: bigint
- let mockUSDTDecimals: number
- let controlledERC20Decimals: number
- if (token0.toLowerCase() === mockUSDTAddress.toLowerCase()) {
- mockUSDTReserve = reserve0
- controlledERC20Reserve = reserve1
- mockUSDTDecimals = 6
- controlledERC20Decimals = 18
- } else {
- mockUSDTReserve = reserve1
- controlledERC20Reserve = reserve0
- mockUSDTDecimals = 6
- controlledERC20Decimals = 18
- }
- // 显示流动性信息
- console.log("\n💧 流动性信息:")
- console.log("MockUSDT储备:", ethers.formatUnits(mockUSDTReserve, mockUSDTDecimals), "mUSDT")
- console.log("ControlledERC20储备:", ethers.formatUnits(controlledERC20Reserve, controlledERC20Decimals), "CTRL")
- // 计算代币价格(考虑小数位数差异)
- const price1 =
- (Number(controlledERC20Reserve) / Number(mockUSDTReserve)) *
- Math.pow(10, mockUSDTDecimals - controlledERC20Decimals)
- const price2 =
- (Number(mockUSDTReserve) / Number(controlledERC20Reserve)) *
- Math.pow(10, controlledERC20Decimals - mockUSDTDecimals)
- console.log("\n💰 价格信息:")
- console.log("1 mUSDT =", price1.toFixed(6), "CTRL")
- console.log("1 CTRL =", price2.toFixed(6), "mUSDT")
- // 获取LP代币总供应量
- const totalSupply = await pair.totalSupply()
- console.log("\n🪙 LP代币信息:")
- console.log("LP代币总供应量:", ethers.formatEther(totalSupply))
- // 检查用户LP代币余额
- const userLPBalance = await pair.balanceOf(wallet.address)
- if (userLPBalance > 0n) {
- console.log("用户LP代币余额:", ethers.formatEther(userLPBalance))
- const userShare = (Number(userLPBalance) / Number(totalSupply)) * 100
- console.log("用户份额:", userShare.toFixed(4) + "%")
- }
- // 模拟不同数量的交易(分析价格影响)
- console.log("\n📈 价格影响分析:")
- const testAmounts = [
- ethers.parseUnits("100", 6), // 100 mUSDT
- ethers.parseUnits("1000", 6), // 1000 mUSDT
- ethers.parseUnits("10000", 6), // 10000 mUSDT
- ]
- for (const amount of testAmounts) {
- try {
- const path = [mockUSDTAddress, controlledERC20Address]
- const amountsOut = await pancakeRouter.getAmountsOut(amount, path)
- const priceImpact = ((Number(amount) - Number(amountsOut[1]) * price1) / Number(amount)) * 100
- console.log(
- `${ethers.formatUnits(amount, 6)} mUSDT -> ${ethers.formatUnits(amountsOut[1], 18)} CTRL (价格影响: ${priceImpact.toFixed(2)}%)`
- )
- } catch (error) {
- console.log(`${ethers.formatUnits(amount, 6)} mUSDT -> 交易失败 (流动性不足)`)
- }
- }
- // 反向交易测试
- console.log("\n📉 反向价格影响分析:")
- const testAmountsReverse = [
- ethers.parseEther("100"), // 100 CTRL
- ethers.parseEther("1000"), // 1000 CTRL
- ethers.parseEther("10000"), // 10000 CTRL
- ]
- for (const amount of testAmountsReverse) {
- try {
- const path = [controlledERC20Address, mockUSDTAddress]
- const amountsOut = await pancakeRouter.getAmountsOut(amount, path)
- const priceImpact = ((Number(amount) - Number(amountsOut[1]) * price2) / Number(amount)) * 100
- console.log(
- `${ethers.formatUnits(amount, 18)} CTRL -> ${ethers.formatUnits(amountsOut[1], 6)} mUSDT (价格影响: ${priceImpact.toFixed(2)}%)`
- )
- } catch (error) {
- console.log(`${ethers.formatUnits(amount, 18)} CTRL -> 交易失败 (流动性不足)`)
- }
- }
- // 获取用户代币余额
- const userMockUSDTBalance = await mockUSDT.balanceOf(wallet.address)
- const userControlledERC20Balance = await controlledERC20.balanceOf(wallet.address)
- console.log("\n👤 用户余额:")
- console.log("MockUSDT余额:", ethers.formatUnits(userMockUSDTBalance, 6), "mUSDT")
- console.log("ControlledERC20余额:", ethers.formatEther(userControlledERC20Balance), "CTRL")
- // 保存信息到文件
- const info = {
- pairAddress: pairAddress,
- reserves: {
- mockUSDT: mockUSDTReserve.toString(),
- controlledERC20: controlledERC20Reserve.toString(),
- },
- prices: {
- mUSDTtoCTRL: price1,
- CTRLtoMUSDT: price2,
- },
- totalSupply: totalSupply.toString(),
- userLPBalance: userLPBalance.toString(),
- userBalances: {
- mockUSDT: userMockUSDTBalance.toString(),
- controlledERC20: userControlledERC20Balance.toString(),
- },
- timestamp: new Date().toISOString(),
- }
- fs.writeFileSync("pancakeswap-info.json", JSON.stringify(info, null, 2))
- console.log("\n💾 信息已保存到 pancakeswap-info.json")
- console.log("\n🔗 PancakeSwap链接:")
- console.log("交易页面: https://testnet.pancakeswap.finance/swap")
- console.log("流动性页面: https://testnet.pancakeswap.finance/liquidity")
- }
- main()
- .then(() => process.exit(0))
- .catch((error) => {
- console.error("❌ 查询失败:", error)
- process.exit(1)
- })
|