mirror of
https://github.com/selfxyz/self.git
synced 2026-04-05 03:00:53 -04:00
Upgrade/update celo sepolia hub kyc (#1725)
* fix: update celo-sepolia in upgrade script to correct chain ID * feat: add celo-sepolia deployed contracts to registry.json * fix: upgrade script now reads version from contract directly * fix: add library linking for kyc related contracts in upgrade script * feat: IdentityVerificationHub v2.13.0 deployed on Celo Sepolia - Implementation: 0x244c93516Abd58E1952452d3D8C4Ce7D454776B8 - Code-only upgrade (no new initializer), adds KYC support - Tx: 0xf24d1c2cd4fd0055237f406a9850ce6e24f538ed09e57ff09755ed142fcc903c * chore: yarn prettier * Feat/new gcp verifier (#1719) * feat: new gcp jwt verifier * lint: contracts --------- Co-authored-by: Nesopie <87437291+Nesopie@users.noreply.github.com>
This commit is contained in:
@@ -37,7 +37,7 @@ import {
|
||||
getLatestVersionInfo,
|
||||
getVersionInfo,
|
||||
getGovernanceConfig,
|
||||
validateReinitializerVersion,
|
||||
readReinitializerVersion,
|
||||
} from "./utils";
|
||||
import { execSync } from "child_process";
|
||||
import * as readline from "readline";
|
||||
@@ -65,7 +65,7 @@ async function promptYesNo(question: string): Promise<boolean> {
|
||||
*/
|
||||
const CHAIN_CONFIG: Record<SupportedNetwork, { chainId: number; safePrefix: string }> = {
|
||||
celo: { chainId: 42220, safePrefix: "celo" },
|
||||
"celo-sepolia": { chainId: 44787, safePrefix: "celo" },
|
||||
"celo-sepolia": { chainId: 11142220, safePrefix: "celo" },
|
||||
sepolia: { chainId: 11155111, safePrefix: "sep" },
|
||||
localhost: { chainId: 31337, safePrefix: "eth" },
|
||||
};
|
||||
@@ -314,39 +314,54 @@ task("upgrade", "Deploy new implementation and create Safe proposal for upgrade"
|
||||
// ========================================================================
|
||||
log.step("Checking reinitializer version...");
|
||||
|
||||
// Check if target version already exists in registry
|
||||
const targetVersionInfo = getVersionInfo(contractId, newVersion);
|
||||
const latestVersionInfo = getLatestVersionInfo(contractId);
|
||||
const latestInitVersion = latestVersionInfo?.info.initializerVersion || 0;
|
||||
|
||||
// If target version exists, use its initializerVersion; otherwise increment latest
|
||||
const expectedInitializerVersion = targetVersionInfo
|
||||
? targetVersionInfo.initializerVersion
|
||||
: (latestVersionInfo?.info.initializerVersion || 0) + 1;
|
||||
let actualReinitVersion: number | null = null;
|
||||
let noNewInitializer = false;
|
||||
|
||||
if (contractFilePath) {
|
||||
const reinitValidation = validateReinitializerVersion(contractFilePath, expectedInitializerVersion);
|
||||
actualReinitVersion = readReinitializerVersion(contractFilePath);
|
||||
|
||||
if (!reinitValidation.valid) {
|
||||
log.error(reinitValidation.error!);
|
||||
if (actualReinitVersion === null) {
|
||||
log.error("Could not find reinitializer in contract file");
|
||||
return;
|
||||
}
|
||||
|
||||
// If target version already exists in registry, validate against its expected version
|
||||
if (targetVersionInfo) {
|
||||
const expected = targetVersionInfo.initializerVersion;
|
||||
if (actualReinitVersion !== expected) {
|
||||
log.error(`Reinitializer mismatch: expected ${expected}, found ${actualReinitVersion}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (actualReinitVersion === latestInitVersion) {
|
||||
// No new reinitializer — code-only upgrade
|
||||
noNewInitializer = true;
|
||||
log.success(`No new initialization needed (reinitializer stays at ${actualReinitVersion})`);
|
||||
} else if (actualReinitVersion === latestInitVersion + 1) {
|
||||
// Standard upgrade with new reinitializer
|
||||
log.success(`Reinitializer version correct: reinitializer(${actualReinitVersion})`);
|
||||
} else {
|
||||
log.error(
|
||||
`Unexpected reinitializer(${actualReinitVersion}). Expected ${latestInitVersion} (no-init) or ${latestInitVersion + 1} (with init)`,
|
||||
);
|
||||
log.box([
|
||||
"REINITIALIZER VERSION MISMATCH",
|
||||
"═".repeat(50),
|
||||
"",
|
||||
`Expected: reinitializer(${expectedInitializerVersion})`,
|
||||
reinitValidation.actual !== null ? `Found: reinitializer(${reinitValidation.actual})` : "Found: none",
|
||||
`Latest registry version has reinitializer: ${latestInitVersion}`,
|
||||
`Contract file has reinitializer: ${actualReinitVersion}`,
|
||||
"",
|
||||
"The initialize function must use the correct reinitializer version.",
|
||||
"Each upgrade should increment the version by 1.",
|
||||
"",
|
||||
"Example pattern:",
|
||||
` function initialize(...) external reinitializer(${expectedInitializerVersion}) {`,
|
||||
" // initialization logic",
|
||||
" }",
|
||||
"Valid options:",
|
||||
` ${latestInitVersion} — code-only upgrade (no new initialization)`,
|
||||
` ${latestInitVersion + 1} — upgrade with new initializer`,
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
log.success(`Reinitializer version correct: reinitializer(${reinitValidation.actual})`);
|
||||
} else {
|
||||
log.warning("Could not locate contract file - skipping reinitializer check");
|
||||
}
|
||||
@@ -389,14 +404,25 @@ task("upgrade", "Deploy new implementation and create Safe proposal for upgrade"
|
||||
|
||||
try {
|
||||
if (contractName === "IdentityVerificationHubImplV2") {
|
||||
const CustomVerifier = await hre.ethers.getContractFactory("CustomVerifier");
|
||||
const customVerifier = await CustomVerifier.deploy();
|
||||
await customVerifier.waitForDeployment();
|
||||
const libraryNames = [
|
||||
"CustomVerifier",
|
||||
"OutputFormatterLib",
|
||||
"ProofVerifierLib",
|
||||
"RegisterProofVerifierLib",
|
||||
"DscProofVerifierLib",
|
||||
"RootCheckLib",
|
||||
"OfacCheckLib",
|
||||
];
|
||||
const libraries: Record<string, string> = {};
|
||||
for (const libName of libraryNames) {
|
||||
const LibFactory = await hre.ethers.getContractFactory(libName);
|
||||
const lib = await LibFactory.deploy();
|
||||
await lib.waitForDeployment();
|
||||
libraries[libName] = await lib.getAddress();
|
||||
log.info(`Deployed library: ${libName} → ${libraries[libName]}`);
|
||||
}
|
||||
|
||||
ContractFactory = await hre.ethers.getContractFactory(contractName, {
|
||||
libraries: { CustomVerifier: await customVerifier.getAddress() },
|
||||
});
|
||||
log.info("Deployed CustomVerifier library for linking");
|
||||
ContractFactory = await hre.ethers.getContractFactory(contractName, { libraries });
|
||||
} else if (
|
||||
contractName === "IdentityRegistryImplV1" ||
|
||||
contractName === "IdentityRegistryIdCardImplV1" ||
|
||||
@@ -593,7 +619,7 @@ task("upgrade", "Deploy new implementation and create Safe proposal for upgrade"
|
||||
log.step("Updating deployment registry...");
|
||||
|
||||
const latestVersion = getLatestVersionInfo(contractId);
|
||||
const newInitializerVersion = (latestVersion?.info.initializerVersion || 0) + 1;
|
||||
const newInitializerVersion = actualReinitVersion ?? (latestVersion?.info.initializerVersion || 0) + 1;
|
||||
const deployerAddress = (await hre.ethers.provider.getSigner()).address;
|
||||
|
||||
addVersion(
|
||||
@@ -602,7 +628,7 @@ task("upgrade", "Deploy new implementation and create Safe proposal for upgrade"
|
||||
newVersion,
|
||||
{
|
||||
initializerVersion: newInitializerVersion,
|
||||
initializerFunction: "initialize", // Always "initialize" - version tracked via reinitializer(N) modifier
|
||||
initializerFunction: noNewInitializer ? "" : "initialize",
|
||||
changelog: changelog || `Upgrade to v${newVersion}`,
|
||||
gitTag: `${contractId.toLowerCase()}-v${newVersion}`,
|
||||
},
|
||||
@@ -680,18 +706,22 @@ task("upgrade", "Deploy new implementation and create Safe proposal for upgrade"
|
||||
|
||||
// Encode initializer function call
|
||||
let initData = "0x";
|
||||
const targetVersionInfoForInit = getVersionInfo(contractId, newVersion);
|
||||
const initializerName = targetVersionInfoForInit?.initializerFunction || `initializeV${newInitializerVersion}`;
|
||||
if (!noNewInitializer) {
|
||||
const targetVersionInfoForInit = getVersionInfo(contractId, newVersion);
|
||||
const initializerName = targetVersionInfoForInit?.initializerFunction || `initializeV${newInitializerVersion}`;
|
||||
|
||||
try {
|
||||
const iface = proxyContract.interface;
|
||||
const initFragment = iface.getFunction(initializerName);
|
||||
if (initFragment && initFragment.inputs.length === 0) {
|
||||
initData = iface.encodeFunctionData(initializerName, []);
|
||||
log.detail("Initializer", initializerName);
|
||||
try {
|
||||
const iface = proxyContract.interface;
|
||||
const initFragment = iface.getFunction(initializerName);
|
||||
if (initFragment && initFragment.inputs.length === 0) {
|
||||
initData = iface.encodeFunctionData(initializerName, []);
|
||||
log.detail("Initializer", initializerName);
|
||||
}
|
||||
} catch {
|
||||
log.detail("Initializer", "None");
|
||||
}
|
||||
} catch {
|
||||
log.detail("Initializer", "None");
|
||||
} else {
|
||||
log.detail("Initializer", "None (code-only upgrade)");
|
||||
}
|
||||
|
||||
// Build upgrade transaction data
|
||||
|
||||
Reference in New Issue
Block a user