feat: add hardhat config and production deployment script
This commit is contained in:
@@ -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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user