Skip to content

Commit 1bd9dd3

Browse files
authored
add tasks (#65)
1 parent e92aadf commit 1bd9dd3

File tree

2 files changed

+265
-1
lines changed

2 files changed

+265
-1
lines changed

src/tasks/flow.ts

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { task } from "hardhat/config";
1+
import { task, types } from "hardhat/config";
22
import { getConfig } from "../config";
33
import { CONTRACTS, getTypedContract } from "../utils/utils";
4+
import { UpgradeableBeacon } from "../../typechain-types";
45

56
task("flow:show", "show contract params").setAction(async (_, hre) => {
67
const flow = await getTypedContract(hre, CONTRACTS.FixedPriceFlow);
@@ -47,3 +48,134 @@ task("flow:updatecontext", "update context to latest").setAction(async (_, hre)
4748
}
4849
console.log(`done.`);
4950
});
51+
52+
task("flow:setAdmin", "Set a new admin for the flow contract")
53+
.addParam("admin", "New admin address", undefined, types.string, false)
54+
.addOptionalParam("key", "Private key to use (defaults to deployer)", undefined, types.string)
55+
.setAction(async (taskArgs: { admin: string; key?: string }, hre) => {
56+
console.log(`Setting new admin for flow contract to: ${taskArgs.admin}`);
57+
58+
// Validate admin address
59+
if (!hre.ethers.isAddress(taskArgs.admin)) {
60+
throw new Error(`Invalid admin address: ${taskArgs.admin}`);
61+
}
62+
63+
let signer;
64+
if (taskArgs.key) {
65+
signer = new hre.ethers.Wallet(taskArgs.key, hre.ethers.provider);
66+
console.log(`Using provided private key, signer address: ${await signer.getAddress()}`);
67+
} else {
68+
const { deployer } = await hre.getNamedAccounts();
69+
signer = await hre.ethers.getSigner(deployer);
70+
console.log(`Using deployer address: ${deployer}`);
71+
}
72+
73+
const flow = await getTypedContract(hre, CONTRACTS.FixedPriceFlow, signer);
74+
const contractAddress = await flow.getAddress();
75+
console.log(`FixedPriceFlow contract address: ${contractAddress}`);
76+
77+
try {
78+
// Check if signer hash PAUSE_ROLE
79+
const PAUSE_ROLE = await flow.PAUSER_ROLE();
80+
const signerAddress = await signer.getAddress();
81+
const hasPauseRole = await flow.hasRole(PAUSE_ROLE, signerAddress);
82+
83+
if (!hasPauseRole) {
84+
throw new Error(`Signer ${signerAddress} does not have PAUSE_ROLE`);
85+
}
86+
87+
// Grant PAUSE_ROLE to new admin
88+
console.log(`Granting PAUSE_ROLE to ${taskArgs.admin}...`);
89+
const pauseTx = await flow.grantRole(PAUSE_ROLE, taskArgs.admin);
90+
console.log(`Grant transaction sent: ${pauseTx.hash}`);
91+
92+
const pauseReceipt = await pauseTx.wait();
93+
if (!pauseReceipt) {
94+
throw new Error("Grant transaction receipt is null");
95+
}
96+
console.log(`Grant transaction confirmed in block: ${pauseReceipt.blockNumber}`);
97+
98+
// Revoke DEFAULT_PAUSE_ROLEADMIN_ROLE from old admin
99+
console.log(`Revoking PAUSE_ROLE from ${signerAddress}...`);
100+
const revokePauseTx = await flow.revokeRole(PAUSE_ROLE, signerAddress);
101+
console.log(`Revoke transaction sent: ${revokePauseTx.hash}`);
102+
103+
const revokePauseReceipt = await revokePauseTx.wait();
104+
if (!revokePauseReceipt) {
105+
throw new Error("Revoke transaction receipt is null");
106+
}
107+
console.log(`Revoke transaction confirmed in block: ${revokePauseReceipt.blockNumber}`);
108+
109+
// Check if signer has DEFAULT_ADMIN_ROLE
110+
const DEFAULT_ADMIN_ROLE = await flow.DEFAULT_ADMIN_ROLE();
111+
const hasAdminRole = await flow.hasRole(DEFAULT_ADMIN_ROLE, signerAddress);
112+
113+
if (!hasAdminRole) {
114+
throw new Error(`Signer ${signerAddress} does not have DEFAULT_ADMIN_ROLE`);
115+
}
116+
117+
// Grant DEFAULT_ADMIN_ROLE to new admin
118+
console.log(`Granting DEFAULT_ADMIN_ROLE to ${taskArgs.admin}...`);
119+
const grantTx = await flow.grantRole(DEFAULT_ADMIN_ROLE, taskArgs.admin);
120+
console.log(`Grant transaction sent: ${grantTx.hash}`);
121+
122+
const grantReceipt = await grantTx.wait();
123+
if (!grantReceipt) {
124+
throw new Error("Grant transaction receipt is null");
125+
}
126+
console.log(`Grant transaction confirmed in block: ${grantReceipt.blockNumber}`);
127+
128+
// Revoke DEFAULT_ADMIN_ROLE from old admin
129+
console.log(`Revoking DEFAULT_ADMIN_ROLE from ${signerAddress}...`);
130+
const revokeTx = await flow.revokeRole(DEFAULT_ADMIN_ROLE, signerAddress);
131+
console.log(`Revoke transaction sent: ${revokeTx.hash}`);
132+
133+
const revokeReceipt = await revokeTx.wait();
134+
if (!revokeReceipt) {
135+
throw new Error("Revoke transaction receipt is null");
136+
}
137+
console.log(`Revoke transaction confirmed in block: ${revokeReceipt.blockNumber}`);
138+
139+
// Verify the changes
140+
const hasNewDefaultAdminRole = await flow.hasRole(DEFAULT_ADMIN_ROLE, taskArgs.admin);
141+
const oldAdminRevokedDefault = !(await flow.hasRole(DEFAULT_ADMIN_ROLE, signerAddress));
142+
const hasNewPauseRole = await flow.hasRole(PAUSE_ROLE, taskArgs.admin);
143+
const oldPauseRevoked = !(await flow.hasRole(PAUSE_ROLE, signerAddress));
144+
145+
if (hasNewDefaultAdminRole && oldAdminRevokedDefault && hasNewPauseRole && oldPauseRevoked) {
146+
console.log(`✅ Successfully transferred PAUSE_ROLE and DEFAULT_ADMIN_ROLE to ${taskArgs.admin}`);
147+
} else {
148+
console.log(`⚠️ Admin transfer completed but verification shows:`);
149+
console.log(` - DEFAULT_ADMIN_ROLE: ${hasNewDefaultAdminRole ? "✓" : "✗"}`);
150+
console.log(` - Old admin revoked: ${oldAdminRevokedDefault ? "✓" : "✗"}`);
151+
}
152+
} catch (error: any) {
153+
console.error(`❌ Failed to set admin: ${error.message}`);
154+
throw error;
155+
}
156+
});
157+
158+
task("flow:transfer-beacon-ownership", "transfer beacon contract ownership")
159+
.addParam("newOwner", "new owner address", undefined, types.string, false)
160+
.addParam("execute", "execute the transfer", false, types.boolean, true)
161+
.setAction(async (taskArgs: { newOwner: string; execute: boolean }, hre) => {
162+
const beaconContract = await hre.ethers.getContract("FixedPriceFlowBeacon");
163+
const beacon = beaconContract as UpgradeableBeacon;
164+
165+
const currentOwner = await beacon.owner();
166+
console.log(`Current owner: ${currentOwner}`);
167+
console.log(`New owner: ${taskArgs.newOwner}`);
168+
169+
if (taskArgs.execute) {
170+
console.log("Transferring beacon ownership...");
171+
const tx = await beacon.transferOwnership(taskArgs.newOwner);
172+
await tx.wait();
173+
console.log(`Ownership transferred! Transaction hash: ${tx.hash}`);
174+
175+
const newOwner = await beacon.owner();
176+
console.log(`New owner confirmed: ${newOwner}`);
177+
} else {
178+
console.log("Dry run complete. Use --execute true to perform the transfer.");
179+
console.log(`Transfer call: beacon.transferOwnership("${taskArgs.newOwner}")`);
180+
}
181+
});

src/tasks/mine.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { task, types } from "hardhat/config";
22
import { CONTRACTS, getTypedContract } from "../utils/utils";
3+
import { UpgradeableBeacon } from "../../typechain-types";
34

45
task("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

Comments
 (0)