pancakeswap-liquidity.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import { MockUSDT__factory, ControlledERC20__factory,IPancakePair__factory } from "../typechain-types"
  2. import { IPancakeRouter02__factory, IPancakeFactory__factory } from "../typechain-types"
  3. import { config as dotenvConfig } from "dotenv"
  4. import { ethers } from "ethers"
  5. import fs from "fs"
  6. // BSC Testnet PancakeSwap V2 合约地址
  7. const PANCAKE_ROUTER_ADDRESS = "0xD99D1c33F9fC3444f8101754aBC46c52416550D1"
  8. const PANCAKE_FACTORY_ADDRESS = "0x6725F303b657a9451d8BA641348b6761A6CC7a17"
  9. const WBNB_ADDRESS = "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd"
  10. /**
  11. * @dev PancakeSwap流动性添加脚本
  12. * 在PancakeSwap V2上为MockUSDT和ControlledERC20创建交易对并添加流动性
  13. * 包含交易对创建、代币授权、流动性添加等功能
  14. */
  15. async function main() {
  16. dotenvConfig()
  17. const rpcUrl = process.env.BSC_TESTNET_RPC_URL
  18. const privateKey = process.env.PRIVATE_KEY
  19. if (!rpcUrl || !privateKey) {
  20. throw new Error("请在.env中配置BSC_TESTNET_RPC_URL和PRIVATE_KEY")
  21. }
  22. const provider = new ethers.JsonRpcProvider(rpcUrl)
  23. const wallet = new ethers.Wallet(privateKey, provider)
  24. console.log("🚀 开始添加PancakeSwap流动性...")
  25. console.log("📝 操作账户:", wallet.address)
  26. console.log("💰 账户余额:", ethers.formatEther(await provider.getBalance(wallet.address)), "BNB")
  27. // 读取部署信息文件(包含合约地址)
  28. let deploymentInfo
  29. try {
  30. deploymentInfo = JSON.parse(fs.readFileSync("deployment-bsc-testnet.json", "utf8"))
  31. } catch (error) {
  32. console.error("❌ 无法读取部署信息文件,请先运行部署脚本")
  33. process.exit(1)
  34. }
  35. const mockUSDTAddress = deploymentInfo.contracts.mockUSDT
  36. const controlledERC20Address = deploymentInfo.contracts.controlledERC20
  37. console.log("📄 MockUSDT地址:", mockUSDTAddress)
  38. console.log("📄 ControlledERC20地址:", controlledERC20Address)
  39. // 获取合约实例
  40. const mockUSDT = MockUSDT__factory.connect(mockUSDTAddress, wallet)
  41. const controlledERC20 = ControlledERC20__factory.connect(controlledERC20Address, wallet)
  42. const pancakeRouter = IPancakeRouter02__factory.connect(PANCAKE_ROUTER_ADDRESS, wallet)
  43. const pancakeFactory = IPancakeFactory__factory.connect(PANCAKE_FACTORY_ADDRESS, wallet)
  44. // 检查代币余额
  45. const mockUSDTBalance = await mockUSDT.balanceOf(wallet.address)
  46. const controlledERC20Balance = await controlledERC20.balanceOf(wallet.address)
  47. console.log("\n💰 代币余额:")
  48. console.log("MockUSDT余额:", ethers.formatUnits(mockUSDTBalance, 6), "mUSDT")
  49. console.log("ControlledERC20余额:", ethers.formatEther(controlledERC20Balance), "CTRL")
  50. // 检查或创建交易对(如果不存在则创建新的交易对)
  51. console.log("\n🔍 检查交易对...")
  52. let pairAddress = await pancakeFactory.getPair(mockUSDTAddress, controlledERC20Address)
  53. if (pairAddress === ethers.ZeroAddress) {
  54. console.log("📦 创建新的交易对...")
  55. const tx = await pancakeFactory.createPair(mockUSDTAddress, controlledERC20Address)
  56. await tx.wait()
  57. pairAddress = await pancakeFactory.getPair(mockUSDTAddress, controlledERC20Address)
  58. console.log("✅ 交易对已创建:", pairAddress)
  59. } else {
  60. console.log("✅ 交易对已存在:", pairAddress)
  61. }
  62. // 授权Router使用代币(允许Router合约转移用户的代币)
  63. console.log("\n🔐 授权Router使用代币...")
  64. const mockUSDTAllowance = await mockUSDT.allowance(wallet.address, PANCAKE_ROUTER_ADDRESS)
  65. if (mockUSDTAllowance < mockUSDTBalance) {
  66. console.log("授权MockUSDT...")
  67. const approveTx = await mockUSDT.approve(PANCAKE_ROUTER_ADDRESS, ethers.MaxUint256)
  68. await approveTx.wait()
  69. console.log("✅ MockUSDT授权完成")
  70. }
  71. const controlledERC20Allowance = await controlledERC20.allowance(wallet.address, PANCAKE_ROUTER_ADDRESS)
  72. if (controlledERC20Allowance < controlledERC20Balance) {
  73. console.log("授权ControlledERC20...")
  74. const approveTx = await controlledERC20.approve(PANCAKE_ROUTER_ADDRESS, ethers.MaxUint256)
  75. await approveTx.wait()
  76. console.log("✅ ControlledERC20授权完成")
  77. }
  78. // 添加流动性到PancakeSwap交易对
  79. console.log("\n💧 添加流动性...")
  80. // 计算添加的流动性数量(使用余额的一半,确保流动性充足)
  81. const mockUSDTAmount = mockUSDTBalance / 2n
  82. const controlledERC20Amount = controlledERC20Balance / 2n
  83. console.log("添加流动性数量:")
  84. console.log("MockUSDT:", ethers.formatUnits(mockUSDTAmount, 6), "mUSDT")
  85. console.log("ControlledERC20:", ethers.formatEther(controlledERC20Amount), "CTRL")
  86. // 设置最小数量(允许1%的滑点保护)
  87. const mockUSDTMin = (mockUSDTAmount * 99n) / 100n
  88. const controlledERC20Min = (controlledERC20Amount * 99n) / 100n
  89. // 添加流动性(设置5分钟的交易截止时间)
  90. const deadline = Math.floor(Date.now() / 1000) + 300 // 5分钟后过期
  91. const addLiquidityTx = await pancakeRouter.addLiquidity(
  92. mockUSDTAddress,
  93. controlledERC20Address,
  94. mockUSDTAmount,
  95. controlledERC20Amount,
  96. mockUSDTMin,
  97. controlledERC20Min,
  98. wallet.address,
  99. deadline
  100. )
  101. console.log("⏳ 等待交易确认...")
  102. const receipt = await addLiquidityTx.wait()
  103. console.log("✅ 流动性添加成功!")
  104. console.log("交易哈希:", receipt!.hash)
  105. // 获取LP代币余额
  106. const pairContract = IPancakePair__factory.connect(pairAddress, wallet)
  107. const lpBalance = await pairContract.balanceOf(wallet.address)
  108. console.log("🪙 LP代币余额:", ethers.formatEther(lpBalance))
  109. // 保存流动性信息
  110. const liquidityInfo = {
  111. pairAddress: pairAddress,
  112. mockUSDTAmount: mockUSDTAmount.toString(),
  113. controlledERC20Amount: controlledERC20Amount.toString(),
  114. lpBalance: lpBalance.toString(),
  115. transactionHash: receipt!.hash,
  116. timestamp: new Date().toISOString(),
  117. }
  118. fs.writeFileSync("liquidity-info.json", JSON.stringify(liquidityInfo, null, 2))
  119. console.log("\n💾 流动性信息已保存到 liquidity-info.json")
  120. console.log("\n🎉 流动性添加完成!")
  121. console.log("📊 交易对地址:", pairAddress)
  122. console.log(
  123. "🔗 PancakeSwap链接: https://testnet.pancakeswap.finance/add/" + mockUSDTAddress + "/" + controlledERC20Address
  124. )
  125. }
  126. main()
  127. .then(() => process.exit(0))
  128. .catch((error) => {
  129. console.error("❌ 添加流动性失败:", error)
  130. process.exit(1)
  131. })