123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import { MockUSDT__factory, ControlledERC20__factory,IPancakePair__factory } from "../typechain-types"
- import { IPancakeRouter02__factory, IPancakeFactory__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流动性添加脚本
- * 在PancakeSwap V2上为MockUSDT和ControlledERC20创建交易对并添加流动性
- * 包含交易对创建、代币授权、流动性添加等功能
- */
- 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)
- console.log("💰 账户余额:", ethers.formatEther(await provider.getBalance(wallet.address)), "BNB")
- // 读取部署信息文件(包含合约地址)
- 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)
- // 检查代币余额
- const mockUSDTBalance = await mockUSDT.balanceOf(wallet.address)
- const controlledERC20Balance = await controlledERC20.balanceOf(wallet.address)
- console.log("\n💰 代币余额:")
- console.log("MockUSDT余额:", ethers.formatUnits(mockUSDTBalance, 6), "mUSDT")
- console.log("ControlledERC20余额:", ethers.formatEther(controlledERC20Balance), "CTRL")
- // 检查或创建交易对(如果不存在则创建新的交易对)
- console.log("\n🔍 检查交易对...")
- let pairAddress = await pancakeFactory.getPair(mockUSDTAddress, controlledERC20Address)
- if (pairAddress === ethers.ZeroAddress) {
- console.log("📦 创建新的交易对...")
- const tx = await pancakeFactory.createPair(mockUSDTAddress, controlledERC20Address)
- await tx.wait()
- pairAddress = await pancakeFactory.getPair(mockUSDTAddress, controlledERC20Address)
- console.log("✅ 交易对已创建:", pairAddress)
- } else {
- console.log("✅ 交易对已存在:", pairAddress)
- }
- // 授权Router使用代币(允许Router合约转移用户的代币)
- console.log("\n🔐 授权Router使用代币...")
- const mockUSDTAllowance = await mockUSDT.allowance(wallet.address, PANCAKE_ROUTER_ADDRESS)
- if (mockUSDTAllowance < mockUSDTBalance) {
- console.log("授权MockUSDT...")
- const approveTx = await mockUSDT.approve(PANCAKE_ROUTER_ADDRESS, ethers.MaxUint256)
- await approveTx.wait()
- console.log("✅ MockUSDT授权完成")
- }
- const controlledERC20Allowance = await controlledERC20.allowance(wallet.address, PANCAKE_ROUTER_ADDRESS)
- if (controlledERC20Allowance < controlledERC20Balance) {
- console.log("授权ControlledERC20...")
- const approveTx = await controlledERC20.approve(PANCAKE_ROUTER_ADDRESS, ethers.MaxUint256)
- await approveTx.wait()
- console.log("✅ ControlledERC20授权完成")
- }
- // 添加流动性到PancakeSwap交易对
- console.log("\n💧 添加流动性...")
- // 计算添加的流动性数量(使用余额的一半,确保流动性充足)
- const mockUSDTAmount = mockUSDTBalance / 2n
- const controlledERC20Amount = controlledERC20Balance / 2n
- console.log("添加流动性数量:")
- console.log("MockUSDT:", ethers.formatUnits(mockUSDTAmount, 6), "mUSDT")
- console.log("ControlledERC20:", ethers.formatEther(controlledERC20Amount), "CTRL")
- // 设置最小数量(允许1%的滑点保护)
- const mockUSDTMin = (mockUSDTAmount * 99n) / 100n
- const controlledERC20Min = (controlledERC20Amount * 99n) / 100n
- // 添加流动性(设置5分钟的交易截止时间)
- const deadline = Math.floor(Date.now() / 1000) + 300 // 5分钟后过期
- const addLiquidityTx = await pancakeRouter.addLiquidity(
- mockUSDTAddress,
- controlledERC20Address,
- mockUSDTAmount,
- controlledERC20Amount,
- mockUSDTMin,
- controlledERC20Min,
- wallet.address,
- deadline
- )
- console.log("⏳ 等待交易确认...")
- const receipt = await addLiquidityTx.wait()
- console.log("✅ 流动性添加成功!")
- console.log("交易哈希:", receipt!.hash)
- // 获取LP代币余额
- const pairContract = IPancakePair__factory.connect(pairAddress, wallet)
- const lpBalance = await pairContract.balanceOf(wallet.address)
- console.log("🪙 LP代币余额:", ethers.formatEther(lpBalance))
- // 保存流动性信息
- const liquidityInfo = {
- pairAddress: pairAddress,
- mockUSDTAmount: mockUSDTAmount.toString(),
- controlledERC20Amount: controlledERC20Amount.toString(),
- lpBalance: lpBalance.toString(),
- transactionHash: receipt!.hash,
- timestamp: new Date().toISOString(),
- }
- fs.writeFileSync("liquidity-info.json", JSON.stringify(liquidityInfo, null, 2))
- console.log("\n💾 流动性信息已保存到 liquidity-info.json")
- console.log("\n🎉 流动性添加完成!")
- console.log("📊 交易对地址:", pairAddress)
- console.log(
- "🔗 PancakeSwap链接: https://testnet.pancakeswap.finance/add/" + mockUSDTAddress + "/" + controlledERC20Address
- )
- }
- main()
- .then(() => process.exit(0))
- .catch((error) => {
- console.error("❌ 添加流动性失败:", error)
- process.exit(1)
- })
|