diff --git a/contracts/_testContracts/OIDImports.sol b/contracts/_testContracts/OIDImports.sol index f2e9b295..1426a07e 100644 --- a/contracts/_testContracts/OIDImports.sol +++ b/contracts/_testContracts/OIDImports.sol @@ -3,6 +3,8 @@ pragma solidity 0.8.17; import "@onchain-id/solidity/contracts/ClaimIssuer.sol"; import "@onchain-id/solidity/contracts/Identity.sol"; +import "@onchain-id/solidity/contracts/factory/IdFactory.sol"; +import "@onchain-id/solidity/contracts/gateway/Gateway.sol"; import "@onchain-id/solidity/contracts/proxy/ImplementationAuthority.sol"; contract OIDImports { diff --git a/hardhat.config.ts b/hardhat.config.ts index 688a158c..86aca0e7 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -4,6 +4,10 @@ import { HardhatUserConfig } from 'hardhat/config'; import 'solidity-coverage'; import '@nomiclabs/hardhat-solhint'; import '@primitivefi/hardhat-dodoc'; +import '@nomiclabs/hardhat-etherscan'; +import * as dotenv from 'dotenv'; + +dotenv.config(); const config: HardhatUserConfig = { solidity: { @@ -21,9 +25,24 @@ const config: HardhatUserConfig = { dodoc: { runOnCompile: false, debugMode: true, - outputDir: "./docgen", + outputDir: './docgen', freshOutput: true, }, + networks: { + mumbai: { + url: process.env.MUMBAI_RPC_URL, + accounts: [`0x${process.env.DEPLOYER_PRIVATE_KEY}`], + }, + polygon: { + url: process.env.POLYGON_RPC_URL, + accounts: [`0x${process.env.DEPLOYER_PRIVATE_KEY}`], + }, + }, + etherscan: { + apiKey: { + polygonMumbai: process.env.POLYGONSCAN_API_KEY, + }, + }, }; export default config; diff --git a/package-lock.json b/package-lock.json index bd7abd63..0c0a2e1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "devDependencies": { "@commitlint/cli": "^17.6.1", "@nomicfoundation/hardhat-toolbox": "^2.0.2", + "@nomiclabs/hardhat-etherscan": "^3.1.8", "@nomiclabs/hardhat-solhint": "^3.0.1", "@onchain-id/solidity": "^2.2.0", "@openzeppelin/contracts": "^4.8.3", @@ -19,6 +20,7 @@ "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "@xyrusworx/hardhat-solidity-json": "^1.0.2", + "dotenv": "^16.4.5", "eslint": "^8.39.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-prettier": "^8.8.0", @@ -2282,11 +2284,11 @@ } }, "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz", - "integrity": "sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.8.tgz", + "integrity": "sha512-v5F6IzQhrsjHh6kQz4uNrym49brK9K5bYCq2zQZ729RYRaifI9hHbtmK+KkIVevfhut7huQFEQ77JLRMAzWYjQ==", + "deprecated": "The @nomiclabs/hardhat-etherscan package is deprecated, please use @nomicfoundation/hardhat-verify instead", "dev": true, - "peer": true, "dependencies": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", @@ -2308,7 +2310,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -2321,7 +2322,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -2336,7 +2336,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "peer": true, "dependencies": { "color-name": "1.1.3" } @@ -2345,15 +2344,13 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@nomiclabs/hardhat-etherscan/node_modules/fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -2368,7 +2365,6 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -2378,7 +2374,6 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "peer": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -2388,7 +2383,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -2398,7 +2392,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -2411,7 +2404,6 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "peer": true, "engines": { "node": ">= 4.0.0" } @@ -3843,7 +3835,6 @@ "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", "dev": true, - "peer": true, "dependencies": { "nofilter": "^3.1.0" }, @@ -4768,6 +4759,18 @@ "node": ">=8" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -8994,7 +8997,6 @@ "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", "dev": true, - "peer": true, "engines": { "node": ">=12.19" } diff --git a/package.json b/package.json index 22aecea2..b18014dd 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ ], "scripts": { "build": "hardhat compile", + "deploy:mumbai": "hardhat run scripts/mumbaiDeploy.ts --network mumbai", "flatten": "node scripts/flatten.js", "coverage": "hardhat coverage", "test": "hardhat test", @@ -43,32 +44,34 @@ "devDependencies": { "@commitlint/cli": "^17.6.1", "@nomicfoundation/hardhat-toolbox": "^2.0.2", + "@nomiclabs/hardhat-etherscan": "^3.1.8", "@nomiclabs/hardhat-solhint": "^3.0.1", "@onchain-id/solidity": "^2.2.0", "@openzeppelin/contracts": "^4.8.3", "@openzeppelin/contracts-upgradeable": "^4.8.3", "@primitivefi/hardhat-dodoc": "^0.2.3", + "@typescript-eslint/eslint-plugin": "^6.7.4", + "@typescript-eslint/parser": "^6.7.4", "@xyrusworx/hardhat-solidity-json": "^1.0.2", + "dotenv": "^16.4.5", "eslint": "^8.39.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-prettier": "^8.8.0", + "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-chai-friendly": "^0.7.2", "eslint-plugin-import": "^2.27.5", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-security": "^1.7.1", + "eth-gas-reporter": "^0.2.27", + "fs-extra": "^11.1.1", + "glob": "^10.2.6", "hardhat": "^2.14.0", "husky": "^8.0.3", "lint-staged": "^13.2.2", "prettier": "^2.8.8", "prettier-plugin-solidity": "^1.1.3", "solhint": "^3.4.1", - "solhint-plugin-prettier": "^0.0.5", - "glob": "^10.2.6", - "fs-extra": "^11.1.1", - "@typescript-eslint/parser": "^6.7.4", - "@typescript-eslint/eslint-plugin": "^6.7.4", - "eslint-import-resolver-typescript": "^3.6.1", - "eth-gas-reporter": "^0.2.27" + "solhint-plugin-prettier": "^0.0.5" }, "lint-staged": { "*.js": [ diff --git a/scripts/mumbaiDeploy.ts b/scripts/mumbaiDeploy.ts new file mode 100644 index 00000000..cc9703c2 --- /dev/null +++ b/scripts/mumbaiDeploy.ts @@ -0,0 +1,452 @@ +import { ethers, run } from 'hardhat'; +import * as dotenv from 'dotenv'; + +dotenv.config(); + +async function main() { + // Load private keys + const deployerPrivateKey = process.env.DEPLOYER_PRIVATE_KEY!; + const interactorPrivateKey = process.env.INTERACTOR_PRIVATE_KEY!; + + // Connect to the network + const deployerWallet = new ethers.Wallet(deployerPrivateKey, ethers.provider); + const interactorWallet = new ethers.Wallet(interactorPrivateKey, ethers.provider); + + // variable used for constructor arguments + let args; + + // Deploy ContractsDeployer contract + const ContractsDeployerFactory = await ethers.getContractFactory('ContractsDeployer', deployerWallet); + const contractsDeployer = await ContractsDeployerFactory.deploy(); + await contractsDeployer.deployed(); + console.log(`ContractsDeployer deployed to: ${contractsDeployer.address}`); + + // Verify ContractsDeployer contract + try { + await run('verify:verify', { + address: contractsDeployer.address, + constructorArguments: [], + network: 'mumbai', + }); + console.log('ContractsDeployer verification successful'); + } catch (error) { + console.error('ContractsDeployer verification failed:', error); + } + + // Add interactor as an agent + let tx = await contractsDeployer.connect(deployerWallet).addAgent(interactorWallet.address); + await tx.wait(); + console.log(`Interactor added as an agent.`); + + // Deploy Token contract via ContractsDeployer + const TokenFactory = await ethers.getContractFactory('Token'); + const tokenBytecode = TokenFactory.bytecode; + tx = await contractsDeployer.connect(interactorWallet).deployContract('Token_v4.1.3', tokenBytecode); + await tx.wait(); + + const deployedTokenAddress = await contractsDeployer.getContract('Token_v4.1.3'); + console.log(`Token contract deployed to: ${deployedTokenAddress}`); + + // Verify Token contract + try { + await run('verify:verify', { + address: deployedTokenAddress, + constructorArguments: [], + network: 'mumbai', + }); + console.log('Token contract verification successful'); + } catch (error) { + console.error('Token contract verification failed:', error); + } + + // Deploy Identity Registry contract via ContractsDeployer + const IRFactory = await ethers.getContractFactory('IdentityRegistry'); + const irBytecode = IRFactory.bytecode; + tx = await contractsDeployer.connect(interactorWallet).deployContract('IR_v4.1.3', irBytecode); + await tx.wait(); + + const deployedIRAddress = await contractsDeployer.getContract('IR_v4.1.3'); + console.log(`IdentityRegistry contract deployed to: ${deployedIRAddress}`); + + // Verify Identity Registry contract + try { + await run('verify:verify', { + address: deployedIRAddress, + constructorArguments: [], + network: 'mumbai', + }); + console.log('IdentityRegistry contract verification successful'); + } catch (error) { + console.error('IdentityRegistry contract verification failed:', error); + } + + // Deploy Identity Registry Storage contract via ContractsDeployer + const IRSFactory = await ethers.getContractFactory('IdentityRegistryStorage'); + const irsBytecode = IRSFactory.bytecode; + tx = await contractsDeployer.connect(interactorWallet).deployContract('IRS_v4.1.3', irsBytecode); + await tx.wait(); + + const deployedIRSAddress = await contractsDeployer.getContract('IRS_v4.1.3'); + console.log(`IdentityRegistryStorage contract deployed to: ${deployedIRSAddress}`); + + // Verify Identity Registry Storage contract + try { + await run('verify:verify', { + address: deployedIRSAddress, + constructorArguments: [], + network: 'mumbai', + }); + console.log('IdentityRegistryStorage contract verification successful'); + } catch (error) { + console.error('IdentityRegistryStorage contract verification failed:', error); + } + + // Deploy Trusted Issuers Registry contract via ContractsDeployer + const TIRFactory = await ethers.getContractFactory('TrustedIssuersRegistry'); + const tirBytecode = TIRFactory.bytecode; + tx = await contractsDeployer.connect(interactorWallet).deployContract('TIR_v4.1.3', tirBytecode); + await tx.wait(); + + const deployedTIRAddress = await contractsDeployer.getContract('TIR_v4.1.3'); + console.log(`IdentityRegistryStorage contract deployed to: ${deployedTIRAddress}`); + + // Verify Trusted Issuers Registry contract + try { + await run('verify:verify', { + address: deployedTIRAddress, + constructorArguments: [], + network: 'mumbai', + }); + console.log('TrustedIssuersRegistry contract verification successful'); + } catch (error) { + console.error('TrustedIssuersRegistry contract verification failed:', error); + } + + // Deploy Claim Topics Registry contract via ContractsDeployer + const CTRFactory = await ethers.getContractFactory('ClaimTopicsRegistry'); + const ctrBytecode = CTRFactory.bytecode; + tx = await contractsDeployer.connect(interactorWallet).deployContract('CTR_v4.1.3', ctrBytecode); + await tx.wait(); + + const deployedCTRAddress = await contractsDeployer.getContract('CTR_v4.1.3'); + console.log(`ClaimTopicsRegistry contract deployed to: ${deployedCTRAddress}`); + + // Verify Claim Topics Registry contract + try { + await run('verify:verify', { + address: deployedCTRAddress, + constructorArguments: [], + network: 'mumbai', + }); + console.log('ClaimTopicsRegistry contract verification successful'); + } catch (error) { + console.error('ClaimTopicsRegistry contract verification failed:', error); + } + + // Deploy Modular Compliance contract via ContractsDeployer + const MCFactory = await ethers.getContractFactory('ModularCompliance'); + const mcBytecode = MCFactory.bytecode; + tx = await contractsDeployer.connect(interactorWallet).deployContract('MC_v4.1.3', mcBytecode); + await tx.wait(); + + const deployedMCAddress = await contractsDeployer.getContract('MC_v4.1.3'); + console.log(`ModularCompliance contract deployed to: ${deployedMCAddress}`); + + // Verify Modular Compliance contract + try { + await run('verify:verify', { + address: deployedMCAddress, + constructorArguments: [], + network: 'mumbai', + }); + console.log('ModularCompliance contract verification successful'); + } catch (error) { + console.error('ModularCompliance contract verification failed:', error); + } + + // Deploy Identity contract via ContractsDeployer + const IdentityFactory = await ethers.getContractFactory('Identity'); + const idBytecode = IdentityFactory.bytecode; + args = ethers.utils.defaultAbiCoder.encode(['address', 'bool'], [contractsDeployer.address, true]); + const idBytecodeWithArgs = idBytecode + args.slice(2); + tx = await contractsDeployer.connect(interactorWallet).deployContract('OID_v2.2.0', idBytecodeWithArgs); + await tx.wait(); + + const deployedOIDAddress = await contractsDeployer.getContract('OID_v2.2.0'); + console.log(`Identity contract deployed to: ${deployedOIDAddress}`); + + // Verify Identity contract + try { + await run('verify:verify', { + address: deployedOIDAddress, + constructorArguments: [contractsDeployer.address, true], + network: 'mumbai', + }); + console.log('Identity contract verification successful'); + } catch (error) { + console.error('Identity contract verification failed:', error); + } + + // Deploy Implementation Authority (OID version) contract via ContractsDeployer + const IdIAFactory = await ethers.getContractFactory('ImplementationAuthority'); + const idiaBytecode = IdIAFactory.bytecode; + args = ethers.utils.defaultAbiCoder.encode(['address'], [deployedOIDAddress]); + const idiaBytecodeWithArgs = idiaBytecode + args.slice(2); + tx = await contractsDeployer.connect(interactorWallet).deployContract('OID_IA_v2.2.0', idiaBytecodeWithArgs); + await tx.wait(); + + const deployedIdIAAddress = await contractsDeployer.getContract('OID_IA_v2.2.0'); + console.log(`ImplementationAuthority contract deployed to: ${deployedIdIAAddress}`); + + // Verify Implementation Authority (OID version) contract + try { + await run('verify:verify', { + address: deployedIdIAAddress, + constructorArguments: [deployedOIDAddress], + network: 'mumbai', + }); + console.log('ImplementationAuthority verification successful'); + } catch (error) { + console.error('ImplementationAuthority verification failed:', error); + } + + // Recover ownership of ImplementationAuthority + tx = await contractsDeployer.connect(interactorWallet).recoverContractOwnership(deployedIdIAAddress, interactorWallet.address); + await tx.wait(); + console.log(`Ownership recovery transaction for ImplementationAuthority sent.`); + + // Create a contract instance for ImplementationAuthority + const implementationAuthorityInstance = await ethers.getContractAt('ImplementationAuthority', deployedIdIAAddress); + + // Check the current owner of the ImplementationAuthority contract + let currentOwner = await implementationAuthorityInstance.owner(); + + // Verify ownership has been transferred to interactorWallet + if (currentOwner.toLowerCase() === interactorWallet.address.toLowerCase()) { + console.log(`Ownership of ImplementationAuthority has been successfully transferred to: ${currentOwner}`); + } else { + console.error(`Ownership transfer of ImplementationAuthority failed. Current owner is: ${currentOwner}`); + } + + // Deploy OID Factory contract via ContractsDeployer + const OIDFactory = await ethers.getContractFactory('IdFactory'); + const oidFactoryBytecode = OIDFactory.bytecode; + args = ethers.utils.defaultAbiCoder.encode(['address'], [deployedIdIAAddress]); + const oidFactoryBytecodeWithArgs = oidFactoryBytecode + args.slice(2); + tx = await contractsDeployer.connect(interactorWallet).deployContract('OID_Factory_v2.2.0', oidFactoryBytecodeWithArgs); + await tx.wait(); + + const deployedOIDFactoryAddress = await contractsDeployer.getContract('OID_Factory_v2.2.0'); + console.log(`IdFactory contract deployed to: ${deployedOIDFactoryAddress}`); + + // Verify OID Factory contract + try { + await run('verify:verify', { + address: deployedOIDFactoryAddress, + constructorArguments: [deployedIdIAAddress], + network: 'mumbai', + }); + console.log('IdFactory verification successful'); + } catch (error) { + console.error('IdFactory verification failed:', error); + } + // Recover ownership of OID Factory + tx = await contractsDeployer.connect(interactorWallet).recoverContractOwnership(deployedOIDFactoryAddress, interactorWallet.address); + await tx.wait(); + console.log(`Ownership recovery transaction for IdFactory initiated.`); + + // Create a contract instance for IdFactory + const oidFactoryContract = await ethers.getContractAt('IdFactory', deployedOIDFactoryAddress, interactorWallet); + + // Check the current owner of the OID Factory contract + currentOwner = await oidFactoryContract.owner(); + if (currentOwner.toLowerCase() === interactorWallet.address.toLowerCase()) { + console.log(`Ownership of IdFactory successfully transferred to ${currentOwner}.`); + } else { + console.error(`Ownership transfer of IdFactory failed. Current owner is ${currentOwner}.`); + } + + // Deploy TREXImplementationAuthority contract via ContractsDeployer + const TREXIAFactory = await ethers.getContractFactory('TREXImplementationAuthority'); + const trexiaBytecode = TREXIAFactory.bytecode; + args = ethers.utils.defaultAbiCoder.encode(['bool', 'address', 'address'], [true, ethers.constants.AddressZero, ethers.constants.AddressZero]); + const trexiaBytecodeWithArgs = trexiaBytecode + args.slice(2); + tx = await contractsDeployer.connect(interactorWallet).deployContract('TREX_IA_v1.0.0', trexiaBytecodeWithArgs); + await tx.wait(); + + const deployedTrexIAAddress = await contractsDeployer.getContract('TREX_IA_v1.0.0'); + console.log(`TREXImplementationAuthority contract deployed to: ${deployedTrexIAAddress}`); + + // Verify TREXImplementationAuthority contract + try { + await run('verify:verify', { + address: deployedTrexIAAddress, + constructorArguments: [true, ethers.constants.AddressZero, ethers.constants.AddressZero], + network: 'mumbai', + }); + console.log('TREXImplementationAuthority verification successful'); + } catch (error) { + console.error('TREXImplementationAuthority verification failed:', error); + } + + // Recover ownership of TREXImplementationAuthority + tx = await contractsDeployer.connect(interactorWallet).recoverContractOwnership(deployedTrexIAAddress, interactorWallet.address); + await tx.wait(); + console.log(`Ownership recovery transaction for TREXImplementationAuthority initiated.`); + + // Create a contract instance for TREXImplementationAuthority + const trexIAContract = await ethers.getContractAt('TREXImplementationAuthority', deployedTrexIAAddress, interactorWallet); + + // Check the current owner of the TREXImplementationAuthority contract + const currentOwnerTrexIA = await trexIAContract.owner(); + if (currentOwnerTrexIA.toLowerCase() === interactorWallet.address.toLowerCase()) { + console.log(`Ownership of TREXImplementationAuthority successfully transferred to ${currentOwnerTrexIA}.`); + } else { + console.error(`Ownership transfer of TREXImplementationAuthority failed. Current owner is ${currentOwnerTrexIA}.`); + } + const version = { + major: 4, + minor: 1, + patch: 3, + }; + + const trexContracts = { + tokenImplementation: deployedTokenAddress, + ctrImplementation: deployedCTRAddress, + irImplementation: deployedIRAddress, + irsImplementation: deployedIRSAddress, + tirImplementation: deployedTIRAddress, + mcImplementation: deployedMCAddress, + }; + tx = await trexIAContract.connect(interactorWallet).addAndUseTREXVersion(version, trexContracts); + const receipt = await tx.wait(); + const trexVersionAddedEvent = receipt.events?.find((e) => e.event === 'TREXVersionAdded'); + const versionUpdatedEvent = receipt.events?.find((e) => e.event === 'VersionUpdated'); + + if (trexVersionAddedEvent && versionUpdatedEvent) { + console.log('TREXVersionAdded and VersionUpdated events were successfully emitted.'); + } else { + console.error('Failed to emit TREXVersionAdded and/or VersionUpdated events.'); + } + // Deploy TREXFactory contract via ContractsDeployer + const TREXFactory = await ethers.getContractFactory('TREXFactory'); + const trexFactoryBytecode = TREXFactory.bytecode; + args = ethers.utils.defaultAbiCoder.encode(['address', 'address'], [deployedTrexIAAddress, deployedOIDFactoryAddress]); + const trexFactoryBytecodeWithArgs = trexFactoryBytecode + args.slice(2); + tx = await contractsDeployer.connect(interactorWallet).deployContract('TREX_Factory_v4.1.3', trexFactoryBytecodeWithArgs); + await tx.wait(); + + const deployedTREXFactoryAddress = await contractsDeployer.getContract('TREX_Factory_v4.1.3'); + console.log(`TREXFactory contract deployed to: ${deployedTREXFactoryAddress}`); + + // Verify TREXFactory contract + try { + await run('verify:verify', { + address: deployedTREXFactoryAddress, + constructorArguments: [deployedTrexIAAddress, deployedOIDFactoryAddress], + network: 'mumbai', + }); + console.log('TREXFactory verification successful'); + } catch (error) { + console.error('TREXFactory verification failed:', error); + } + // Recover ownership of TREXFactory + tx = await contractsDeployer.connect(interactorWallet).recoverContractOwnership(deployedTREXFactoryAddress, interactorWallet.address); + await tx.wait(); + console.log(`Ownership recovery transaction for TREXFactory initiated.`); + + // Verify the ownership transfer + const trexFactoryContract = await ethers.getContractAt('TREXFactory', deployedTREXFactoryAddress, interactorWallet); + const currentOwnerTREXFactory = await trexFactoryContract.owner(); + if (currentOwnerTREXFactory.toLowerCase() === interactorWallet.address.toLowerCase()) { + console.log(`Ownership of TREXFactory successfully transferred to ${currentOwnerTREXFactory}.`); + } else { + console.error(`Ownership transfer of TREXFactory failed. Current owner is ${currentOwnerTREXFactory}.`); + } + // Deploy TREXGateway contract via ContractsDeployer + const TREXGatewayFactory = await ethers.getContractFactory('TREXGateway'); + const trexGatewayBytecode = TREXGatewayFactory.bytecode; + const argsTREXGateway = ethers.utils.defaultAbiCoder.encode( + ['address', 'bool'], + [deployedTREXFactoryAddress, false], // Using the deployed TREXFactory address and setting publicDeploymentStatus to false + ); + const trexGatewayBytecodeWithArgs = trexGatewayBytecode + argsTREXGateway.slice(2); + tx = await contractsDeployer.connect(interactorWallet).deployContract('TREX_Gateway', trexGatewayBytecodeWithArgs); + await tx.wait(); + + const deployedTREXGatewayAddress = await contractsDeployer.getContract('TREX_Gateway'); + console.log(`TREXGateway contract deployed to: ${deployedTREXGatewayAddress}`); + + try { + await run('verify:verify', { + address: deployedTREXGatewayAddress, + constructorArguments: [deployedTREXFactoryAddress, false], + network: 'mumbai', + }); + console.log('TREXGateway verification successful'); + } catch (error) { + console.error('TREXGateway verification failed:', error); + } + // Recover ownership of TREXGateway + tx = await contractsDeployer.connect(interactorWallet).recoverContractOwnership(deployedTREXGatewayAddress, interactorWallet.address); + await tx.wait(); + console.log(`Ownership recovery transaction for TREXGateway initiated.`); + + // Confirm the ownership transfer + const trexGatewayContract = await ethers.getContractAt('Ownable', deployedTREXGatewayAddress, interactorWallet); + const currentOwnerTREXGateway = await trexGatewayContract.owner(); + if (currentOwnerTREXGateway.toLowerCase() === interactorWallet.address.toLowerCase()) { + console.log(`Ownership of TREXGateway successfully transferred to ${currentOwnerTREXGateway}.`); + } else { + console.error(`Ownership transfer of TREXGateway failed. Current owner is ${currentOwnerTREXGateway}.`); + } + tx = await trexFactoryContract.connect(interactorWallet).transferOwnership(deployedTREXGatewayAddress); + await tx.wait(); + console.log(`Ownership of TREX Factory transferred to TREXGateway.`); + tx = await oidFactoryContract.connect(interactorWallet).addTokenFactory(deployedTREXFactoryAddress); + await tx.wait(); + console.log(`TREX Factory registered in IdFactory as a Token Factory`); + + // Deploy Gateway contract via ContractsDeployer + const GatewayFactory = await ethers.getContractFactory('Gateway'); + const gatewayBytecode = GatewayFactory.bytecode; + args = ethers.utils.defaultAbiCoder.encode(['address', 'address[]'], [deployedOIDFactoryAddress, []]); + const gatewayBytecodeWithArgs = gatewayBytecode + args.slice(2); + tx = await contractsDeployer.connect(interactorWallet).deployContract('Gateway', gatewayBytecodeWithArgs); + await tx.wait(); + + const deployedGatewayAddress = await contractsDeployer.getContract('Gateway'); + console.log(`Gateway contract deployed to: ${deployedGatewayAddress}`); + + try { + await run('verify:verify', { + address: deployedGatewayAddress, + constructorArguments: [deployedOIDFactoryAddress, []], + network: 'mumbai', + }); + console.log('Gateway verification successful'); + } catch (error) { + console.error('Gateway verification failed:', error); + } + // Recover ownership of Gateway + tx = await contractsDeployer.connect(interactorWallet).recoverContractOwnership(deployedGatewayAddress, interactorWallet.address); + await tx.wait(); + console.log(`Ownership recovery transaction for Gateway initiated.`); + + // Confirm the ownership transfer + const gatewayContract = await ethers.getContractAt('Gateway', deployedGatewayAddress, interactorWallet); + const currentOwnerGateway = await gatewayContract.owner(); + if (currentOwnerGateway.toLowerCase() === interactorWallet.address.toLowerCase()) { + console.log(`Ownership of Gateway successfully transferred to ${currentOwnerGateway}.`); + } else { + console.error(`Ownership transfer of Gateway failed. Current owner is ${currentOwnerGateway}.`); + } + tx = await oidFactoryContract.connect(interactorWallet).transferOwnership(deployedGatewayAddress); + await tx.wait(); + console.log(`Ownership of TREX Factory transferred to TREXGateway.`); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +});