-
Notifications
You must be signed in to change notification settings - Fork 1
/
l1-deployer-cli.sh
executable file
·414 lines (373 loc) · 13.8 KB
/
l1-deployer-cli.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
#!/usr/bin/env bash
deploy_all_flag=false
deploy_vanilla_flag=false
deploy_avs_flag=false
deploy_middleware_flag=false
deploy_router_flag=false
skip_release_verification_flag=false
resume_flag=false
wallet_type=""
chain=""
chain_id=0
deploy_contract=""
priority_gas_price=""
with_gas_price=""
help() {
echo "Usage:"
echo " $0 <command> --chain <chain> <wallet option> [optional options]"
echo
echo "Commands (one required):"
echo " deploy-all Deploy all components (vanilla, AVS, middleware, router)."
echo " deploy-vanilla Deploy and verify the VanillaRegistry contract to L1."
echo " deploy-avs Deploy and verify the MevCommitAVS contract to L1."
echo " deploy-middleware Deploy and verify the MevCommitMiddleware contract to L1."
echo " deploy-router Deploy and verify the ValidatorOptInRouter contract to L1."
echo
echo "Required Options:"
echo " --chain, -c <chain> Specify the chain to deploy to ('mainnet' or 'holesky')."
echo
echo "Wallet Options (exactly one required):"
echo " --keystore Use a keystore for deployment."
echo " --ledger Use a Ledger hardware wallet for deployment."
echo " --trezor Use a Trezor hardware wallet for deployment."
echo
echo "Optional Options:"
echo " --skip-release-verification Skip the GitHub release verification step."
echo " --resume Resume the deployment process if previously interrupted."
echo " --priority-gas-price <price> Sets the priority gas price for EIP1559 transactions. Useful for when gas prices are volatile and you want to get your transaction included."
echo " --with-gas-price <price> Sets the gas price for broadcasted legacy transactions, or the max fee for broadcasted EIP1559 transactions."
echo " --help Display this help message."
echo
echo "Notes:"
echo " - Exactly one command and one wallet option must be specified."
echo " - Options and commands can be specified in any order."
echo " - Required arguments must immediately follow their options."
echo
echo "Environment Variables Required:"
echo " For Keystore:"
echo " KEYSTORES Path(s) to keystore(s) passed to forge script as --keystores flag."
echo " KEYSTORE_PASSWORD Password(s) for keystore(s) passed to forge script as --password flag."
echo " SENDER Address of the sender."
echo " RPC_URL RPC URL for the deployment chain."
echo " ETHERSCAN_API_KEY API key for etherscan contract verification."
echo
echo " For Ledger or Trezor:"
echo " HD_PATHS Derivation path(s) for hardware wallets passed to forge script as --hd-paths flag."
echo " SENDER Address of the sender."
echo " RPC_URL RPC URL for the deployment chain."
echo
echo "Examples:"
echo " $0 deploy-all --chain mainnet --keystore --priority-gas-price 2000000000 --with-gas-price 5000000000"
echo " $0 --ledger deploy-avs --chain holesky --priority-gas-price 2000000000 --with-gas-price 5000000000"
echo " $0 --chain holesky deploy-middleware --trezor --priority-gas-price 2000000000 --with-gas-price 5000000000"
echo " $0 --chain mainnet --keystore --resume --priority-gas-price 2000000000 --with-gas-price 5000000000"
exit 1
}
usage() {
echo "Usage:"
echo " $0 <command> --chain <chain> [wallet option] [options]"
echo
echo "Use '$0 --help' to see available commands and options."
exit 1
}
check_dependencies() {
local missing_utils=()
local required_utilities=(
git
forge
cast
curl
jq
)
for util in "${required_utilities[@]}"; do
if ! command -v "${util}" &> /dev/null; then
missing_utils+=("${util}")
fi
done
if [[ ${#missing_utils[@]} -ne 0 ]]; then
echo "Error: The following required utilities are not installed: ${missing_utils[*]}."
exit 1
fi
}
parse_args() {
if [[ $# -eq 0 ]]; then
usage
fi
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
deploy-all)
deploy_all_flag=true
shift
;;
deploy-vanilla)
deploy_vanilla_flag=true
shift
;;
deploy-avs)
deploy_avs_flag=true
shift
;;
deploy-middleware)
deploy_middleware_flag=true
shift
;;
deploy-router)
deploy_router_flag=true
shift
;;
--chain|-c)
if [[ -z "$2" ]]; then
echo "Error: --chain requires an argument."
exit 1
fi
chain="$2"
if [[ "$chain" != "mainnet" && "$chain" != "holesky" ]]; then
echo "Error: Unknown chain '$chain'. Valid options are 'mainnet' or 'holesky'."
exit 1
fi
shift 2
;;
--skip-release-verification)
skip_release_verification_flag=true
shift
;;
--resume)
resume_flag=true
shift
;;
--keystore)
if [[ -n "$wallet_type" ]]; then
echo "Error: Multiple wallet types specified. Please specify only one of --keystore, --ledger, or --trezor."
exit 1
fi
wallet_type="keystore"
shift
;;
--ledger)
if [[ -n "$wallet_type" ]]; then
echo "Error: Multiple wallet types specified. Please specify only one of --keystore, --ledger, or --trezor."
exit 1
fi
wallet_type="ledger"
shift
;;
--trezor)
if [[ -n "$wallet_type" ]]; then
echo "Error: Multiple wallet types specified. Please specify only one of --keystore, --ledger, or --trezor."
exit 1
fi
wallet_type="trezor"
shift
;;
--priority-gas-price)
if [[ -z "$2" ]]; then
echo "Error: --priority-gas-price requires an argument."
exit 1
fi
priority_gas_price="$2"
shift 2
;;
--with-gas-price)
if [[ -z "$2" ]]; then
echo "Error: --with-gas-price requires an argument."
exit 1
fi
with_gas_price="$2"
shift 2
;;
--help)
help
;;
*)
echo "Error: Unknown command or option '$1'."
usage
;;
esac
done
if [[ -z "$chain" ]]; then
echo "Error: The --chain option is required."
usage
fi
if [[ -z "$wallet_type" ]]; then
echo "Error: A wallet option is required. Please specify one of --keystore, --ledger, or --trezor."
usage
fi
commands_specified=0
for flag in deploy_all_flag deploy_vanilla_flag deploy_avs_flag deploy_middleware_flag deploy_router_flag; do
if [[ "${!flag}" == true ]]; then
((commands_specified++))
fi
done
if [[ $commands_specified -eq 0 ]]; then
echo "Error: No command specified."
usage
elif [[ $commands_specified -gt 1 ]]; then
echo "Error: Multiple commands specified. Please specify only one command at a time."
usage
fi
}
check_env_variables() {
local missing_vars=()
local required_vars=("SENDER" "RPC_URL" "ETHERSCAN_API_KEY")
if [[ "$wallet_type" == "keystore" ]]; then
required_vars+=("KEYSTORES" "KEYSTORE_PASSWORD")
elif [[ "$wallet_type" == "ledger" || "$wallet_type" == "trezor" ]]; then
required_vars+=("HD_PATHS")
fi
for var in "${required_vars[@]}"; do
if [[ -z "${!var}" ]]; then
missing_vars+=("${var}")
fi
done
if [[ ${#missing_vars[@]} -ne 0 ]]; then
echo "Error: The following environment variables are not set: ${missing_vars[*]}."
echo "Please set them before running the script."
exit 1
fi
}
get_chain_params() {
if [[ "$chain" == "mainnet" ]]; then
chain_id=1
deploy_contract="DeployMainnet"
elif [[ "$chain" == "holesky" ]]; then
chain_id=17000
deploy_contract="DeployHolesky"
fi
}
check_git_status() {
if ! current_tag=$(git describe --tags --exact-match 2>/dev/null); then
echo "Error: Current commit is not tagged. Please ensure the commit is tagged before deploying."
exit 1
fi
if [[ -n "$(git status --porcelain)" ]]; then
echo "Error: There are uncommitted changes. Please commit or stash them before deploying."
exit 1
fi
if [[ "$skip_release_verification_flag" != true ]]; then
releases_url="https://api.github.com/repos/primev/mev-commit/releases?per_page=100"
releases_json=$(curl -s "$releases_url")
if [[ -z "$releases_json" ]]; then
echo "Error: Unable to fetch releases from GitHub."
exit 1
fi
release_tags=$(echo "$releases_json" | jq -r '.[].tag_name')
if echo "$release_tags" | grep -q "^$current_tag$"; then
echo "Tag '$current_tag' is associated with a release on GitHub."
else
echo "Error: Tag '$current_tag' is not associated with any release on GitHub. Please create a release for this tag before deploying."
exit 1
fi
else
echo "Skipping release verification as per user request."
fi
}
check_rpc_url() {
queried_chain_id=$(cast chain-id --rpc-url "$RPC_URL" 2>/dev/null)
cast_exit_code=$?
if [[ $cast_exit_code -ne 0 ]]; then
echo "Error: Failed to retrieve chain ID using the provided RPC URL."
echo "Please ensure the RPC URL is correct and accessible."
exit 1
fi
if [[ "$queried_chain_id" -ne "$chain_id" ]]; then
echo "Error: RPC URL does not match the expected chain ID."
echo "Expected chain ID: $chain_id, but got: $queried_chain_id."
exit 1
fi
if [[ "$RPC_URL" != *"alchemy"* && "$RPC_URL" != *"infura"* ]]; then
echo "Are you using a public rate-limited RPC URL? If so, contract verification may fail."
read -p "Do you want to continue? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Exiting script."
exit 1
fi
fi
}
check_etherscan_api_key() {
response=$(curl -s "https://api.etherscan.io/api?module=account&action=balance&address=${SENDER}&tag=latest&apikey=${ETHERSCAN_API_KEY}")
status=$(echo "$response" | grep -o '"status":"[0-9]"' | cut -d':' -f2 | tr -d '"')
if [[ "$status" != "1" ]]; then
echo "Error: Etherscan API call failed or invalid etherscan API key."
exit 1
fi
}
deploy_contract_generic() {
local script_path="$1"
forge clean
declare -a forge_args=()
forge_args+=("script" "${script_path}:${deploy_contract}")
forge_args+=("--rpc-url" "${RPC_URL}")
forge_args+=("--sender" "${SENDER}")
forge_args+=("--via-ir")
forge_args+=("--chain-id" "${chain_id}")
forge_args+=("--use" "0.8.26")
forge_args+=("--broadcast")
forge_args+=("--verify")
if [[ -n "$priority_gas_price" ]]; then
forge_args+=("--priority-gas-price" "${priority_gas_price}")
fi
if [[ -n "$with_gas_price" ]]; then
forge_args+=("--with-gas-price" "${with_gas_price}")
fi
if [[ "$resume_flag" == true ]]; then
forge_args+=("--resume")
fi
if [[ "$wallet_type" == "keystore" ]]; then
forge_args+=("--keystores" "${KEYSTORES}")
forge_args+=("--password" "${KEYSTORE_PASSWORD}")
elif [[ "$wallet_type" == "ledger" ]]; then
forge_args+=("--ledger")
forge_args+=("--hd-paths" "${HD_PATHS}")
elif [[ "$wallet_type" == "trezor" ]]; then
forge_args+=("--trezor")
forge_args+=("--hd-paths" "${HD_PATHS}")
fi
if forge "${forge_args[@]}"; then
echo "Successfully ran ${script_path} on chain ID ${chain_id} using ${wallet_type}."
echo "Remember to update documentation with new contract addresses!"
else
echo "Error: Failed to run ${script_path} on chain ID ${chain_id} using ${wallet_type}."
exit 1
fi
}
deploy_vanilla() {
deploy_contract_generic "scripts/validator-registry/DeployVanillaRegistry.s.sol"
}
deploy_avs() {
deploy_contract_generic "scripts/validator-registry/avs/DeployAVS.s.sol"
}
deploy_middleware() {
deploy_contract_generic "scripts/validator-registry/middleware/DeployMiddleware.s.sol"
}
deploy_router() {
deploy_contract_generic "scripts/validator-registry/DeployValidatorOptInRouter.s.sol"
}
main() {
check_dependencies
parse_args "$@"
check_env_variables
get_chain_params
check_git_status
check_rpc_url
check_etherscan_api_key
if [[ "${deploy_all_flag}" == true ]]; then
echo "Deploying all contracts to $chain using $wallet_type..."
deploy_vanilla
deploy_avs
deploy_middleware
deploy_router
elif [[ "${deploy_vanilla_flag}" == true ]]; then
deploy_vanilla
elif [[ "${deploy_avs_flag}" == true ]]; then
deploy_avs
elif [[ "${deploy_middleware_flag}" == true ]]; then
deploy_middleware
elif [[ "${deploy_router_flag}" == true ]]; then
deploy_router
else
usage
fi
}
main "$@"