11import { task , types } from "hardhat/config" ;
22import { CONTRACTS , getTypedContract } from "../utils/utils" ;
3+ import { UpgradeableBeacon } from "../../typechain-types" ;
34
45task ( "mine:show" , "show contract params" ) . setAction ( async ( _ , hre ) => {
56 const mine = await getTypedContract ( hre , CONTRACTS . PoraMine ) ;
@@ -30,3 +31,134 @@ task("mine:setNumSubtasks", "set num subtasks")
3031 await ( await mine . setNumSubtasks ( taskArgs . n ) ) . wait ( ) ;
3132 console . log ( `set num subtasks to ${ taskArgs . n } ` ) ;
3233 } ) ;
34+
35+ task ( "mine:setAdmin" , "Set a new admin for the mine contract" )
36+ . addParam ( "admin" , "New admin address" , undefined , types . string , false )
37+ . addOptionalParam ( "key" , "Private key to use (defaults to deployer)" , undefined , types . string )
38+ . setAction ( async ( taskArgs : { admin : string ; key ?: string } , hre ) => {
39+ console . log ( `Setting new admin for mine contract to: ${ taskArgs . admin } ` ) ;
40+
41+ // Validate admin address
42+ if ( ! hre . ethers . isAddress ( taskArgs . admin ) ) {
43+ throw new Error ( `Invalid admin address: ${ taskArgs . admin } ` ) ;
44+ }
45+
46+ let signer ;
47+ if ( taskArgs . key ) {
48+ signer = new hre . ethers . Wallet ( taskArgs . key , hre . ethers . provider ) ;
49+ console . log ( `Using provided private key, signer address: ${ await signer . getAddress ( ) } ` ) ;
50+ } else {
51+ const { deployer } = await hre . getNamedAccounts ( ) ;
52+ signer = await hre . ethers . getSigner ( deployer ) ;
53+ console . log ( `Using deployer address: ${ deployer } ` ) ;
54+ }
55+
56+ const mine = await getTypedContract ( hre , CONTRACTS . PoraMine , signer ) ;
57+ const contractAddress = await mine . getAddress ( ) ;
58+ console . log ( `PoraMine contract address: ${ contractAddress } ` ) ;
59+
60+ try {
61+ // Check if signer hash PARAMS_ADMIN_ROLE
62+ const PARAMS_ADMIN_ROLE = await mine . PARAMS_ADMIN_ROLE ( ) ;
63+ const signerAddress = await signer . getAddress ( ) ;
64+ const hasParamsAdminRole = await mine . hasRole ( PARAMS_ADMIN_ROLE , signerAddress ) ;
65+
66+ if ( ! hasParamsAdminRole ) {
67+ throw new Error ( `Signer ${ signerAddress } does not have PARAMS_ADMIN_ROLE` ) ;
68+ }
69+
70+ // Grant PARAMS_ADMIN_ROLE to new admin
71+ console . log ( `Granting PARAMS_ADMIN_ROLE to ${ taskArgs . admin } ...` ) ;
72+ const paramTx = await mine . grantRole ( PARAMS_ADMIN_ROLE , taskArgs . admin ) ;
73+ console . log ( `Grant transaction sent: ${ paramTx . hash } ` ) ;
74+
75+ const paramReceipt = await paramTx . wait ( ) ;
76+ if ( ! paramReceipt ) {
77+ throw new Error ( "Grant transaction receipt is null" ) ;
78+ }
79+ console . log ( `Grant transaction confirmed in block: ${ paramReceipt . blockNumber } ` ) ;
80+
81+ // Revoke PARAMS_ADMIN_ROLE from old admin
82+ console . log ( `Revoking PARAMS_ADMIN_ROLE from ${ signerAddress } ...` ) ;
83+ const revokeParamTx = await mine . revokeRole ( PARAMS_ADMIN_ROLE , signerAddress ) ;
84+ console . log ( `Revoke transaction sent: ${ revokeParamTx . hash } ` ) ;
85+
86+ const revokeParamReceipt = await revokeParamTx . wait ( ) ;
87+ if ( ! revokeParamReceipt ) {
88+ throw new Error ( "Revoke transaction receipt is null" ) ;
89+ }
90+ console . log ( `Revoke transaction confirmed in block: ${ revokeParamReceipt . blockNumber } ` ) ;
91+
92+ // Check if signer has DEFAULT_ADMIN_ROLE
93+ const DEFAULT_ADMIN_ROLE = await mine . DEFAULT_ADMIN_ROLE ( ) ;
94+ const hasAdminRole = await mine . hasRole ( DEFAULT_ADMIN_ROLE , signerAddress ) ;
95+
96+ if ( ! hasAdminRole ) {
97+ throw new Error ( `Signer ${ signerAddress } does not have DEFAULT_ADMIN_ROLE` ) ;
98+ }
99+
100+ // Grant DEFAULT_ADMIN_ROLE to new admin
101+ console . log ( `Granting DEFAULT_ADMIN_ROLE to ${ taskArgs . admin } ...` ) ;
102+ const grantTx = await mine . grantRole ( DEFAULT_ADMIN_ROLE , taskArgs . admin ) ;
103+ console . log ( `Grant transaction sent: ${ grantTx . hash } ` ) ;
104+
105+ const grantReceipt = await grantTx . wait ( ) ;
106+ if ( ! grantReceipt ) {
107+ throw new Error ( "Grant transaction receipt is null" ) ;
108+ }
109+ console . log ( `Grant transaction confirmed in block: ${ grantReceipt . blockNumber } ` ) ;
110+
111+ // Revoke DEFAULT_ADMIN_ROLE from old admin
112+ console . log ( `Revoking DEFAULT_ADMIN_ROLE from ${ signerAddress } ...` ) ;
113+ const revokeTx = await mine . revokeRole ( DEFAULT_ADMIN_ROLE , signerAddress ) ;
114+ console . log ( `Revoke transaction sent: ${ revokeTx . hash } ` ) ;
115+
116+ const revokeReceipt = await revokeTx . wait ( ) ;
117+ if ( ! revokeReceipt ) {
118+ throw new Error ( "Revoke transaction receipt is null" ) ;
119+ }
120+ console . log ( `Revoke transaction confirmed in block: ${ revokeReceipt . blockNumber } ` ) ;
121+
122+ // Verify the changes
123+ const hasNewDefaultAdminRole = await mine . hasRole ( DEFAULT_ADMIN_ROLE , taskArgs . admin ) ;
124+ const oldAdminRevokedDefault = ! ( await mine . hasRole ( DEFAULT_ADMIN_ROLE , signerAddress ) ) ;
125+ const hasNewParamsAdminRole = await mine . hasRole ( PARAMS_ADMIN_ROLE , taskArgs . admin ) ;
126+ const oldAdminRevokedParams = ! ( await mine . hasRole ( PARAMS_ADMIN_ROLE , signerAddress ) ) ;
127+
128+ if ( hasNewDefaultAdminRole && oldAdminRevokedDefault && hasNewParamsAdminRole && oldAdminRevokedParams ) {
129+ console . log ( `✅ Successfully transferred PARAMS_ADMIN_ROLE and DEFAULT_ADMIN_ROLE to ${ taskArgs . admin } ` ) ;
130+ } else {
131+ console . log ( `⚠️ Admin transfer completed but verification shows:` ) ;
132+ console . log ( ` - DEFAULT_ADMIN_ROLE: ${ hasNewDefaultAdminRole ? "✓" : "✗" } ` ) ;
133+ console . log ( ` - Old admin revoked: ${ oldAdminRevokedDefault ? "✓" : "✗" } ` ) ;
134+ }
135+ } catch ( error : any ) {
136+ console . error ( `❌ Failed to set admin: ${ error . message } ` ) ;
137+ throw error ;
138+ }
139+ } ) ;
140+
141+ task ( "mine:transfer-beacon-ownership" , "transfer beacon contract ownership" )
142+ . addParam ( "newOwner" , "new owner address" , undefined , types . string , false )
143+ . addParam ( "execute" , "execute the transfer" , false , types . boolean , true )
144+ . setAction ( async ( taskArgs : { newOwner : string ; execute : boolean } , hre ) => {
145+ const beaconContract = await hre . ethers . getContract ( "PoraMineBeacon" ) ;
146+ const beacon = beaconContract as UpgradeableBeacon ;
147+
148+ const currentOwner = await beacon . owner ( ) ;
149+ console . log ( `Current owner: ${ currentOwner } ` ) ;
150+ console . log ( `New owner: ${ taskArgs . newOwner } ` ) ;
151+
152+ if ( taskArgs . execute ) {
153+ console . log ( "Transferring beacon ownership..." ) ;
154+ const tx = await beacon . transferOwnership ( taskArgs . newOwner ) ;
155+ await tx . wait ( ) ;
156+ console . log ( `Ownership transferred! Transaction hash: ${ tx . hash } ` ) ;
157+
158+ const newOwner = await beacon . owner ( ) ;
159+ console . log ( `New owner confirmed: ${ newOwner } ` ) ;
160+ } else {
161+ console . log ( "Dry run complete. Use --execute true to perform the transfer." ) ;
162+ console . log ( `Transfer call: beacon.transferOwnership("${ taskArgs . newOwner } ")` ) ;
163+ }
164+ } ) ;
0 commit comments