Skip to content

Commit a8db34d

Browse files
authored
feat(protocol-contracts): add task:acceptOwnership on Safe (#1290)
* feat(protocol-contracts): add task:acceptOwnership on Safe * revert(protocol-contracts): unwanted deployer wallet changes * chore(protocol-contracts): remove governance_deployer from required config * chore(protocol-contracts): minor naming changes
1 parent 26baa4b commit a8db34d

23 files changed

+210
-133
lines changed

protocol-contracts/deployment-cli/.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# ================================================
66
# Wallet Configuration
77
# ================================================
8-
# Private keys for protocol deployment and contract deployment
8+
# Private keys for protocol deployment and governance contracts deployment
99
PROTOCOL_DEPLOYER_PRIVATE_KEY=0x...
1010
DEPLOYER_PRIVATE_KEY=0x...
1111

protocol-contracts/deployment-cli/deployment-state/deployment-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ networks:
2727
layerzero_config: "layerzero.config.testnet.ts" # LayerZero config file for this environment
2828

2929
wallets:
30-
governance_deployer:
31-
description: "Governance deployer (deploys Aragon DAO, only exists during Phase 1)"
32-
private_key_env: "GOVERNANCE_DEPLOYER_PRIVATE_KEY"
3330
protocol_deployer:
3431
description: "Protocol deployer (owns governance until DAO takes over)"
3532
private_key_env: "PROTOCOL_DEPLOYER_PRIVATE_KEY"
33+
deployer:
34+
description: "Deployer for gateway and host contracts"
35+
private_key_env: "DEPLOYER_PRIVATE_KEY"
3636

3737
operators:
3838
- name: "Operator 1"

protocol-contracts/deployment-cli/src/config/schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ export const DeploymentConfigSchema = z.object({
214214
"At least one network environment must be defined",
215215
),
216216
wallets: z.object({
217-
governance_deployer: WalletSchema,
218217
protocol_deployer: WalletSchema,
218+
deployer: WalletSchema,
219219
}),
220220
operators: z.array(OperatorSchema).min(1),
221221
protocol: ProtocolSchema,

protocol-contracts/deployment-cli/src/steps/step-02-safe.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,36 @@ export class Step02Safe extends BaseStep {
1818
ctx: DeploymentContext,
1919
): Promise<StepExecutionResult> {
2020
const gateway = ctx.networks.getGateway();
21-
const deployerPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
21+
const protocolDeployerPk =
22+
ctx.env.resolveWalletPrivateKey("protocol_deployer");
2223
const projectRoot = resolveProjectRoot();
2324
const reader = new TaskOutputReader(projectRoot);
2425

2526
const baseEnv = ctx.env.buildTaskEnv({
26-
PRIVATE_KEY: deployerPk,
27+
PRIVATE_KEY: protocolDeployerPk,
2728
RPC_URL_ZAMA_GATEWAY_TESTNET: gateway.rpcUrl,
2829
});
2930

3031
// Check if Safe is already deployed
3132
const taskOutput = new TaskOutputReader(projectRoot);
32-
let safeAddress: string | undefined;
33+
let safeProxyAddress: string | undefined;
3334
try {
34-
safeAddress = taskOutput.readHardhatDeployment(
35+
safeProxyAddress = taskOutput.readHardhatDeployment(
3536
this.pkgName,
3637
gateway.name,
3738
"SafeL2Proxy",
3839
);
3940
} catch (_error) {
40-
safeAddress = undefined;
41+
safeProxyAddress = undefined;
4142
}
4243

43-
if (safeAddress) {
44+
if (safeProxyAddress) {
4445
ctx.logger.info(
4546
"Safe artifact found, reading existing deployment...",
4647
);
47-
ctx.logger.success(`Using existing Safe proxy at ${safeAddress}`);
48+
ctx.logger.success(
49+
`Using existing Safe proxy at ${safeProxyAddress}`,
50+
);
4851
} else {
4952
// Compile before deploying
5053
ctx.logger.info("Compiling Safe contracts...");
@@ -64,16 +67,22 @@ export class Step02Safe extends BaseStep {
6467
env: baseEnv,
6568
});
6669

67-
safeAddress = reader.readHardhatDeployment(
70+
safeProxyAddress = reader.readHardhatDeployment(
6871
this.pkgName,
6972
gateway.name,
7073
"SafeL2Proxy",
7174
);
72-
ctx.logger.success(`Deployed Safe proxy at ${safeAddress}`);
75+
ctx.logger.success(`Deployed Safe proxy at ${safeProxyAddress}`);
7376
}
74-
77+
const safeAddress = reader.readHardhatDeployment(
78+
this.pkgName,
79+
gateway.name,
80+
"SafeL2",
81+
);
82+
ctx.env.recordAddress("SAFE_ADDRESS", safeAddress, this.id);
7583
return {
7684
addresses: {
85+
SAFE_PROXY_ADDRESS: safeProxyAddress,
7786
SAFE_ADDRESS: safeAddress,
7887
},
7988
notes: [
@@ -85,14 +94,13 @@ export class Step02Safe extends BaseStep {
8594

8695
protected async verifyDeployments(
8796
ctx: DeploymentContext,
88-
result: StepExecutionResult,
97+
_result: StepExecutionResult,
8998
): Promise<void> {
9099
const gateway = ctx.networks.getGateway();
91-
const deployerPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
92-
const safeAddress = result.addresses?.SAFE_ADDRESS;
93-
100+
const protocolDeployerPk =
101+
ctx.env.resolveWalletPrivateKey("protocol_deployer");
94102
const baseEnv = ctx.env.buildTaskEnv({
95-
PRIVATE_KEY: deployerPk,
103+
PRIVATE_KEY: protocolDeployerPk,
96104
RPC_URL_ZAMA_GATEWAY_TESTNET: gateway.rpcUrl,
97105
});
98106

@@ -109,6 +117,9 @@ export class Step02Safe extends BaseStep {
109117
ctx.logger.warn(
110118
"Safe verification failed (this may be acceptable if already verified)",
111119
);
120+
ctx.logger.error(
121+
_error instanceof Error ? _error.message : String(_error),
122+
);
112123
}
113124

114125
// AdminModule verification is performed in Step 03 after it is deployed with the correct ADMIN_ACCOUNT (receiver)

protocol-contracts/deployment-cli/src/steps/step-03-layerzero.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class Step03LayerzeroLink extends BaseStep {
2222

2323
protected async validate(ctx: DeploymentContext): Promise<void> {
2424
const dao = ctx.env.getAddress("DAO_ADDRESS");
25-
const safe = ctx.env.getAddress("SAFE_ADDRESS");
25+
const safe = ctx.env.getAddress("SAFE_PROXY_ADDRESS");
2626

2727
if (!dao) {
2828
throw new ValidationError(
@@ -43,9 +43,9 @@ export class Step03LayerzeroLink extends BaseStep {
4343
const gatewayNetwork = ctx.networks.getGateway();
4444
const protocolPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
4545
const daoAddress = ctx.env.getAddress("DAO_ADDRESS");
46-
const safeAddress = ctx.env.getAddress("SAFE_ADDRESS");
46+
const safeProxyAddress = ctx.env.getAddress("SAFE_PROXY_ADDRESS");
4747

48-
if (!daoAddress || !safeAddress) {
48+
if (!daoAddress || !safeProxyAddress) {
4949
throw new ValidationError(
5050
"DAO and Safe addresses are required before executing Step 3.",
5151
);
@@ -56,7 +56,7 @@ export class Step03LayerzeroLink extends BaseStep {
5656
SEPOLIA_RPC_URL: ethereumNetwork.rpcUrl,
5757
RPC_URL_ZAMA_GATEWAY_TESTNET: gatewayNetwork.rpcUrl,
5858
DAO_ADDRESS: daoAddress,
59-
SAFE_ADDRESS: safeAddress,
59+
SAFE_PROXY_ADDRESS: safeProxyAddress,
6060
ETHERSCAN_API: ethereumNetwork.explorerApiKey,
6161
BLOCKSCOUT_API: gatewayNetwork.blockscoutApiUrl,
6262
});
@@ -124,7 +124,7 @@ export class Step03LayerzeroLink extends BaseStep {
124124
PRIVATE_KEY: protocolPk,
125125
RPC_URL_ZAMA_GATEWAY_TESTNET: gatewayNetwork.rpcUrl,
126126
ADMIN_ADDRESS: receiverAddress,
127-
SAFE_ADDRESS: safeAddress,
127+
SAFE_PROXY_ADDRESS: safeProxyAddress,
128128
});
129129
await ctx.hardhat.runTask({
130130
pkg: "protocol-contracts/safe",
@@ -205,7 +205,7 @@ export class Step03LayerzeroLink extends BaseStep {
205205
`Transferring GovernanceOAppSender ownership to DAO (${daoAddress}) and...`,
206206
);
207207
ctx.logger.info(
208-
`Transferring GovernanceOAppReceiver ownership to Safe (${safeAddress})...`,
208+
`Transferring GovernanceOAppReceiver ownership to Safe (${safeProxyAddress})...`,
209209
);
210210
await ctx.hardhat.runTask({
211211
pkg: this.pkgName,
@@ -236,14 +236,14 @@ export class Step03LayerzeroLink extends BaseStep {
236236
const networkEnvironment = ctx.networks.getSelectedEnvironment();
237237
const protocolPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
238238
const daoAddress = ctx.env.getAddress("DAO_ADDRESS");
239-
const safeAddress = ctx.env.getAddress("SAFE_ADDRESS");
239+
const safeProxyAddress = ctx.env.getAddress("SAFE_PROXY_ADDRESS");
240240

241241
const baseEnv = ctx.env.buildTaskEnv({
242242
PRIVATE_KEY: protocolPk,
243243
SEPOLIA_RPC_URL: ethereumNetwork.rpcUrl,
244244
RPC_URL_ZAMA_GATEWAY_TESTNET: gatewayNetwork.rpcUrl,
245245
DAO_ADDRESS: daoAddress,
246-
SAFE_ADDRESS: safeAddress,
246+
SAFE_PROXY_ADDRESS: safeProxyAddress,
247247
ETHERSCAN_API: ethereumNetwork.explorerApiKey,
248248
BLOCKSCOUT_API: gatewayNetwork.blockscoutApiUrl,
249249
});

protocol-contracts/deployment-cli/src/steps/step-04-token.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ export class Step04TokenDeployment extends BaseStep {
2929
if (!receiver) {
3030
throw new ValidationError("DAO address is required before Step 4.");
3131
}
32-
const safeAddress = ctx.env.getAddress("SAFE_ADDRESS");
33-
if (!safeAddress) {
32+
const safeProxyAddress = ctx.env.getAddress("SAFE_PROXY_ADDRESS");
33+
if (!safeProxyAddress) {
3434
throw new ValidationError(
3535
"Safe address is required before Step 4.",
3636
);
@@ -44,9 +44,9 @@ export class Step04TokenDeployment extends BaseStep {
4444
const gateway = ctx.networks.getGateway();
4545
const protocolPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
4646
const daoAddress = ctx.env.getAddress("DAO_ADDRESS");
47-
const safeAddress = ctx.env.getAddress("SAFE_ADDRESS");
47+
const safeProxyAddress = ctx.env.getAddress("SAFE_PROXY_ADDRESS");
4848

49-
if (!daoAddress || !safeAddress) {
49+
if (!daoAddress || !safeProxyAddress) {
5050
throw new ValidationError(
5151
"Required prerequisite addresses missing before token deployment.",
5252
);
@@ -59,7 +59,7 @@ export class Step04TokenDeployment extends BaseStep {
5959
SEPOLIA_RPC_URL: ethereum.rpcUrl,
6060
RPC_URL_ZAMA_GATEWAY_TESTNET: gateway.rpcUrl,
6161
DAO_ADDRESS: daoAddress,
62-
SAFE_ADDRESS: safeAddress,
62+
SAFE_PROXY_ADDRESS: safeProxyAddress,
6363
NUM_INITIAL_RECEIVERS: recipients.length.toString(),
6464
};
6565

@@ -132,7 +132,7 @@ export class Step04TokenDeployment extends BaseStep {
132132
task: "zama:oft:setDelegate",
133133
args: [
134134
"--address",
135-
safeAddress,
135+
safeProxyAddress,
136136
"--from-deployment",
137137
"true",
138138
"--network",
@@ -143,7 +143,7 @@ export class Step04TokenDeployment extends BaseStep {
143143
task: "zama:oft:transferOwnership",
144144
args: [
145145
"--address",
146-
safeAddress,
146+
safeProxyAddress,
147147
"--from-deployment",
148148
"true",
149149
"--network",
@@ -175,15 +175,13 @@ export class Step04TokenDeployment extends BaseStep {
175175
const gateway = ctx.networks.getGateway();
176176
const protocolPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
177177
const daoAddress = ctx.env.getAddress("DAO_ADDRESS");
178-
const safeAddress = ctx.env.getAddress("SAFE_ADDRESS");
179178

180179
const baseEnv = ctx.env.buildTaskEnv({
181180
PRIVATE_KEY: protocolPk,
182181
INITIAL_ADMIN: ctx.config.wallets.protocol_deployer.address,
183182
SEPOLIA_RPC_URL: ethereum.rpcUrl,
184183
RPC_URL_ZAMA_GATEWAY_TESTNET: gateway.rpcUrl,
185184
DAO_ADDRESS: daoAddress,
186-
SAFE_ADDRESS: safeAddress,
187185
ETHERSCAN_API: ethereum.explorerApiKey,
188186
BLOCKSCOUT_API: gateway.blockscoutApiUrl,
189187
});

protocol-contracts/deployment-cli/src/steps/step-06-gateway-contracts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class Step06GatewayContracts extends BaseStep {
3434
ctx: DeploymentContext,
3535
): Promise<StepExecutionResult> {
3636
const gateway = ctx.networks.getGateway();
37-
const deployerPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
37+
const deployerPk = ctx.env.resolveWalletPrivateKey("deployer");
3838

3939
// Build environment variables from config
4040
const baseEnvVars: Record<string, string> = {
@@ -187,7 +187,7 @@ export class Step06GatewayContracts extends BaseStep {
187187

188188
protected async verifyDeployments(ctx: DeploymentContext): Promise<void> {
189189
const gateway = ctx.networks.getGateway();
190-
const deployerPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
190+
const deployerPk = ctx.env.resolveWalletPrivateKey("deployer");
191191

192192
const baseEnvVars: Record<string, string> = {
193193
DEPLOYER_PRIVATE_KEY: deployerPk,

protocol-contracts/deployment-cli/src/steps/step-07-host-contracts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class Step07HostContracts extends BaseStep {
2222
): Promise<StepExecutionResult> {
2323
const ethereum = ctx.networks.getEthereum();
2424
const gateway = ctx.networks.getGateway();
25-
const deployerPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
25+
const deployerPk = ctx.env.resolveWalletPrivateKey("deployer");
2626

2727
const gatewayProvider = new ethers.JsonRpcProvider(gateway.rpcUrl);
2828
const gatewayNetwork = await gatewayProvider.getNetwork();
@@ -133,7 +133,7 @@ export class Step07HostContracts extends BaseStep {
133133
protected async verifyDeployments(ctx: DeploymentContext): Promise<void> {
134134
const ethereum = ctx.networks.getEthereum();
135135
const gateway = ctx.networks.getGateway();
136-
const deployerPk = ctx.env.resolveWalletPrivateKey("protocol_deployer");
136+
const deployerPk = ctx.env.resolveWalletPrivateKey("deployer");
137137

138138
const gatewayProvider = new ethers.JsonRpcProvider(gateway.rpcUrl);
139139
const gatewayNetwork = await gatewayProvider.getNetwork();

0 commit comments

Comments
 (0)