Files
assetxContracts/scripts/upgrade/upgradeYTAssetVault.ts

220 lines
9.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ethers, upgrades } from "hardhat";
import * as fs from "fs";
import * as path from "path";
/**
* 升级 YTAssetVault 合约
*
* 升级步骤:
* 1. 部署新的 YTAssetVault 实现合约
* 2. 通过 Factory 更新 vaultImplementation 地址
* 3. 可选:批量升级现有的 Vault 代理合约
*
* 注意:
* - 升级后,新创建的 vault 将使用新实现
* - 已存在的 vault 需要手动升级才能使用新功能
*/
async function main() {
const [deployer] = await ethers.getSigners();
console.log("\n==========================================");
console.log("🔄 升级 YTAssetVault 系统");
console.log("==========================================");
console.log("升级账户:", deployer.address);
console.log("账户余额:", ethers.formatEther(await ethers.provider.getBalance(deployer.address)), "ETH\n");
// ========== 读取部署信息 ==========
const deploymentsPath = path.join(__dirname, "../../deployments-vault-system.json");
if (!fs.existsSync(deploymentsPath)) {
throw new Error("未找到部署信息文件 deployments-vault-system.json请先运行部署脚本");
}
const deployments = JSON.parse(fs.readFileSync(deploymentsPath, "utf-8"));
if (!deployments.contracts?.YTAssetVault?.implementation) {
throw new Error("未找到 YTAssetVault 部署信息");
}
console.log("📋 当前部署的合约:");
console.log(" YTAssetVault Implementation (旧):", deployments.contracts.YTAssetVault.implementation);
console.log(" YTAssetFactory Proxy: ", deployments.contracts.YTAssetFactory.proxy);
console.log(" YTAssetFactory Implementation: ", deployments.contracts.YTAssetFactory.implementation);
console.log(" 已创建的 Vaults 数量: ", deployments.vaults?.length || 0);
console.log("");
// ========== Phase 1: 部署新的 YTAssetVault 实现 ==========
console.log("🔄 Phase 1: 部署新的 YTAssetVault 实现合约");
console.log(" 编译新的 YTAssetVault 合约...");
const YTAssetVaultV2 = await ethers.getContractFactory("YTAssetVault");
console.log(" 部署新实现合约...");
const newVaultImpl = await YTAssetVaultV2.deploy();
await newVaultImpl.waitForDeployment();
const newVaultImplAddress = await newVaultImpl.getAddress();
console.log(" ✅ 新 YTAssetVault Implementation:", newVaultImplAddress);
console.log("");
// ========== Phase 2: 通过 Factory 更新实现地址 ==========
console.log("🔄 Phase 2: 通过 Factory 更新 vaultImplementation");
const factory = await ethers.getContractAt(
"YTAssetFactory",
deployments.contracts.YTAssetFactory.proxy
);
console.log(" 当前 Factory 的 vaultImplementation:", await factory.vaultImplementation());
console.log(" 准备更新为新实现地址...");
const updateTx = await factory.setVaultImplementation(newVaultImplAddress);
await updateTx.wait();
console.log(" ✅ Factory vaultImplementation 已更新!");
console.log(" 新地址:", await factory.vaultImplementation());
console.log("");
// ========== Phase 3: 升级现有的 Vault 代理(可选) ==========
console.log("🔄 Phase 3: 升级现有的 Vault 代理合约");
const existingVaults = deployments.vaults || [];
if (existingVaults.length === 0) {
console.log(" ⚠️ 没有已部署的 Vault跳过此步骤");
} else {
console.log(` 发现 ${existingVaults.length} 个已部署的 Vault\n`);
// 询问是否升级现有 Vault在实际使用中可以配置
const UPGRADE_EXISTING_VAULTS = true; // 设置为 true 自动升级所有 vault
const VAULTS_TO_UPGRADE: number[] = [0, 1, 2]; // 可以指定要升级的 vault 索引,如 [0, 1]
if (UPGRADE_EXISTING_VAULTS) {
console.log(" 📝 准备升级现有的 Vault 代理合约...\n");
const vaultsToProcess = VAULTS_TO_UPGRADE.length > 0
? VAULTS_TO_UPGRADE
: existingVaults.map((_: any, idx: number) => idx);
for (const idx of vaultsToProcess) {
const vaultInfo = existingVaults[idx];
if (!vaultInfo) {
console.log(` ⚠️ 索引 ${idx} 无效,跳过`);
continue;
}
console.log(` [${idx + 1}/${vaultsToProcess.length}] 升级 ${vaultInfo.symbol} (${vaultInfo.address})`);
try {
// 通过 Factory 调用 upgradeVault
const upgradeTx = await factory.upgradeVault(
vaultInfo.address,
newVaultImplAddress
);
await upgradeTx.wait();
// 验证升级
const vault = await ethers.getContractAt("YTAssetVault", vaultInfo.address);
const currentImpl = await upgrades.erc1967.getImplementationAddress(vaultInfo.address);
if (currentImpl.toLowerCase() === newVaultImplAddress.toLowerCase()) {
console.log(` ✅ 升级成功!新实现: ${currentImpl}`);
// 验证新功能(检查是否有排队提现机制)
try {
const pendingCount = await vault.pendingRequestsCount();
console.log(` ✅ 新功能验证通过pendingRequestsCount: ${pendingCount}`);
} catch (e) {
console.log(` ⚠️ 新功能验证失败,可能升级未完全生效`);
}
// 更新部署信息中的实现地址
vaultInfo.implementationAddress = currentImpl;
vaultInfo.lastUpgraded = new Date().toISOString();
} else {
console.log(` ⚠️ 升级可能未成功,当前实现: ${currentImpl}`);
}
} catch (error: any) {
console.log(` ❌ 升级失败: ${error.message}`);
}
console.log("");
}
} else {
console.log(" 配置为不自动升级现有 Vault");
console.log(" 💡 提示:可以稍后通过 Factory.upgradeVault() 手动升级\n");
}
}
// ========== 保存更新的部署信息 ==========
// 保存旧的实现地址作为历史记录
if (!deployments.upgradeHistory) {
deployments.upgradeHistory = [];
}
deployments.upgradeHistory.push({
timestamp: new Date().toISOString(),
oldImplementation: deployments.contracts.YTAssetVault.implementation,
newImplementation: newVaultImplAddress,
upgrader: deployer.address
});
// 更新当前实现地址
deployments.contracts.YTAssetVault.implementation = newVaultImplAddress;
deployments.lastUpdate = new Date().toISOString();
fs.writeFileSync(deploymentsPath, JSON.stringify(deployments, null, 2));
console.log("💾 升级信息已保存到:", deploymentsPath);
// ========== 升级总结 ==========
console.log("\n🎉 升级总结:");
console.log("=====================================");
console.log("旧 YTAssetVault Implementation:");
console.log(" ", deployments.upgradeHistory[deployments.upgradeHistory.length - 1].oldImplementation);
console.log("");
console.log("新 YTAssetVault Implementation:");
console.log(" ", newVaultImplAddress);
console.log("");
console.log("Factory Proxy (不变):");
console.log(" ", deployments.contracts.YTAssetFactory.proxy);
console.log("");
console.log("已升级的 Vaults:");
if (existingVaults.length > 0) {
existingVaults.forEach((v: any, idx: number) => {
if (v.lastUpgraded) {
console.log(` ✅ [${idx}] ${v.symbol}: ${v.address}`);
} else {
console.log(` ⏸️ [${idx}] ${v.symbol}: ${v.address} (未升级)`);
}
});
} else {
console.log(" (无)");
}
console.log("=====================================\n");
console.log("✅ 升级完成!");
console.log("");
console.log("📌 重要提示:");
console.log(" 1. Factory 已更新为新实现,新创建的 vault 将使用新版本");
console.log(" 2. 已升级的 vault 代理地址不变,状态数据已保留");
console.log(" 3. 新增功能:");
console.log(" • 两阶段提现机制(排队领取)");
console.log(" • WithdrawRequest 请求记录");
console.log(" • processBatchWithdrawals 批量处理");
console.log(" • 多个查询函数(请求详情、队列进度等)");
console.log(" 4. 如有未升级的 vault可通过以下方式升级");
console.log(" factory.upgradeVault(vaultAddress, newImplementation)");
console.log("");
console.log("📝 下一步:");
console.log(" 1. 在测试环境验证新功能");
console.log(" 2. 测试 withdrawYT 的排队机制");
console.log(" 3. 测试 processBatchWithdrawals 的批量处理");
console.log(" 4. 确认所有查询函数工作正常");
console.log(" 5. 主网升级前务必充分测试\n");
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});