From e1094b09d5242d6286a6f85bb7171cc8c4c1c620 Mon Sep 17 00:00:00 2001 From: Bot Date: Sun, 30 Aug 2026 23:42:56 +0800 Subject: [PATCH] feat: add hardhat config and production deployment script --- hardhat.config.js | 38 +++++++++++++ package.json | 17 ++++++ scripts/deploy.js | 133 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 hardhat.config.js create mode 100644 package.json create mode 100644 scripts/deploy.js diff --git a/hardhat.config.js b/hardhat.config.js new file mode 100644 index 0000000..3c3ef8a --- /dev/null +++ b/hardhat.config.js @@ -0,0 +1,38 @@ +require("@nomicfoundation/hardhat-toolbox"); +require("dotenv").config(); + +const PRIVATE_KEY = process.env.PRIVATE_KEY || "0x0000000000000000000000000000000000000000000000000000000000000001"; + +module.exports = { + solidity: { + version: "0.8.29", + settings: { + evmVersion: "cancun", + optimizer: { + enabled: true, + runs: 200 + } + } + }, + paths: { + sources: "./main/src", + tests: "./test", + cache: "./cache", + artifacts: "./artifacts" + }, + networks: { + localhost: { + url: "http://127.0.0.1:8545" + }, + robinhoodTestnet: { + url: process.env.ROBINHOOD_TESTNET_RPC || "https://rpc.testnet.chain.robinhood.com", + chainId: 46630, + accounts: [PRIVATE_KEY] + }, + robinhoodMainnet: { + url: process.env.ROBINHOOD_MAINNET_RPC || "https://rpc.chain.robinhood.com", + chainId: 46631, // 根据 Robinhood Chain 主网 ChainId 确认 + accounts: [PRIVATE_KEY] + } + } +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..a76cae5 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "wtf-contract", + "version": "2.0.0", + "description": "WTFX Core Smart Contracts & Deployment Scripts", + "scripts": { + "compile": "hardhat compile", + "test": "hardhat test", + "deploy:robinhood-testnet": "hardhat run scripts/deploy.js --network robinhoodTestnet", + "deploy:robinhood-mainnet": "hardhat run scripts/deploy.js --network robinhoodMainnet", + "deploy:local": "hardhat run scripts/deploy.js --network localhost" + }, + "devDependencies": { + "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "dotenv": "^16.4.5", + "hardhat": "^2.22.5" + } +} diff --git a/scripts/deploy.js b/scripts/deploy.js new file mode 100644 index 0000000..63ca1d0 --- /dev/null +++ b/scripts/deploy.js @@ -0,0 +1,133 @@ +const hre = require("hardhat"); +const fs = require("fs"); +const path = require("path"); + +async function main() { + const [deployer] = await hre.ethers.getSigners(); + const networkName = hre.network.name; + console.log(`====================================================`); + console.log(`Deploying WTFX Protocol v2 to [${networkName}]`); + console.log(`Deployer Address: ${deployer.address}`); + console.log(`==================================================== +`); + + // 1. 部署测试抵押品 WUSD (若主网则直接使用真实 USDC/WUSD 地址) + let collateralAddress = process.env.COLLATERAL_ADDRESS; + if (!collateralAddress || networkName === "localhost" || networkName === "robinhoodTestnet") { + console.log("Deploying Mock WUSD Collateral..."); + const MockERC20 = await hre.ethers.getContractFactory("MockERC20"); + const mockWUSD = await MockERC20.deploy("WTF USD", "WUSD", 18); + await mockWUSD.waitForDeployment(); + collateralAddress = await mockWUSD.getAddress(); + console.log(`Mock WUSD Deployed at: ${collateralAddress}`); + } else { + console.log(`Using existing Collateral at: ${collateralAddress}`); + } + + // 2. 部署 PowerLDACurveV2 联合曲线引擎 + console.log("Deploying PowerLDACurveV2 Engine..."); + // 曲线标准参数 (18位精度定点数) + const c1 = hre.ethers.parseUnits("1", 18); + const c2 = hre.ethers.parseUnits("1", 18); + const start = 0; + const timeKinkStart = 0; + const timeKinkEnd = 86400 * 7; + const rateBaseMin = hre.ethers.parseUnits("0.001", 18); + const rateBaseMax = hre.ethers.parseUnits("0.05", 18); + const lsRoot = hre.ethers.parseUnits("1", 18); + const tick = 100; + const phiDeltaMax = hre.ethers.parseUnits("0.1", 18); + const windowStatic = 3600; + + const PowerLDACurveV2 = await hre.ethers.getContractFactory("PowerLDACurveV2"); + const curve = await PowerLDACurveV2.deploy( + c1, c2, start, timeKinkStart, timeKinkEnd, rateBaseMin, rateBaseMax, lsRoot, tick, phiDeltaMax, windowStatic + ); + await curve.waitForDeployment(); + const curveAddress = await curve.getAddress(); + console.log(`PowerLDACurveV2 Deployed at: ${curveAddress}`); + + // 3. 部署 Registry 库与 WTFControllerV2 实现合约 + console.log("Deploying Registry Library & WTFControllerV2 Implementation..."); + const WTFControllerV2 = await hre.ethers.getContractFactory("WTFControllerV2"); + const controllerImpl = await WTFControllerV2.deploy(); + await controllerImpl.waitForDeployment(); + const implAddress = await controllerImpl.getAddress(); + console.log(`WTFControllerV2 Implementation Deployed at: ${implAddress}`); + + // 4. 部署 TestProxy 代理并初始化 Controller + console.log("Deploying Proxy Contract..."); + const TestProxy = await hre.ethers.getContractFactory("TestProxy"); + const proxy = await TestProxy.deploy(implAddress); + await proxy.waitForDeployment(); + const proxyAddress = await proxy.getAddress(); + console.log(`WTFControllerV2 Proxy Deployed at: ${proxyAddress}`); + + const controller = await hre.ethers.getContractAt("WTFControllerV2", proxyAddress); + + // 初始化参数 + const admin = deployer.address; + const treasury = process.env.TREASURY_ADDRESS || deployer.address; + const defaultFeeRate = hre.ethers.parseUnits("0.006", 18); // 0.6% + const adminTransferDelay = 86400 * 3; // 3 天延迟 + + console.log("Initializing WTFControllerV2 Proxy..."); + const initTx = await controller.initialize(admin, treasury, defaultFeeRate, adminTransferDelay); + await initTx.wait(); + console.log("WTFControllerV2 Proxy Initialized!"); + + // 5. 治理初始化:白名单与标准档位 + console.log("Whitelisting Collateral & Curve in Controller..."); + const seedMin = hre.ethers.parseUnits("1", 18); + const wlCollateralTx = await controller.setCollateralWhitelisted(collateralAddress, true, seedMin); + await wlCollateralTx.wait(); + + const wlCurveTx = await controller.setCurveWhitelisted(curveAddress, true); + await wlCurveTx.wait(); + + console.log("Setting Standard Market Tiers (Tier 1/2/3)..."); + // Tier 1: PvP ($3,000 WUSD, 50k Supply, 10 min dispute) + await (await controller.setMarketTier(1, hre.ethers.parseUnits("3000", 18), hre.ethers.parseUnits("50000", 18), 600)).wait(); + // Tier 2: Community ($25,000 WUSD, 300k Supply, 2 hours dispute) + await (await controller.setMarketTier(2, hre.ethers.parseUnits("25000", 18), hre.ethers.parseUnits("300000", 18), 7200)).wait(); + // Tier 3: Flagship ($100,000 WUSD, 1,000k Supply, 24 hours dispute) + await (await controller.setMarketTier(3, hre.ethers.parseUnits("100000", 18), hre.ethers.parseUnits("1000000", 18), 86400)).wait(); + + console.log("All Governance Tiers Configured Successfully!"); + + // 6. 导出部署产物为 JSON (供 Admin 前端、Web 交易端、Indexer 读取) + const deployOutput = { + network: networkName, + chainId: (await hre.ethers.provider.getNetwork()).chainId.toString(), + timestamp: new Date().toISOString(), + deployer: deployer.address, + contracts: { + collateral: collateralAddress, + powerLDACurve: curveAddress, + controllerImplementation: implAddress, + controllerProxy: proxyAddress + }, + governance: { + admin: admin, + treasury: treasury, + defaultFeeRate: defaultFeeRate.toString(), + adminTransferDelay: adminTransferDelay + } + }; + + const outputDir = path.join(__dirname, "../deployments"); + if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true }); + const outputFile = path.join(outputDir, `${networkName}.json`); + fs.writeFileSync(outputFile, JSON.stringify(deployOutput, null, 2)); + + console.log(` +====================================================`); + console.log(`Deployment summary exported to: ${outputFile}`); + console.log(`==================================================== +`); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +});