Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding --dry-run & --quiet Arguments for Testing Vanity Safe Addresses #457

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 50 additions & 27 deletions src/safe_cli/safe_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

def get_usage_msg():
return """
safe-creator [-h] [-v] [--threshold THRESHOLD] [--owners OWNERS [OWNERS ...]] [--safe-contract SAFE_CONTRACT] [--proxy-factory PROXY_FACTORY] [--callback-handler CALLBACK_HANDLER] [--salt-nonce SALT_NONCE] [--without-events] node_url private_key
safe-creator [-h] [-v] [--quiet] [--threshold THRESHOLD] [--owners OWNERS [OWNERS ...]] [--safe-contract SAFE_CONTRACT] [--proxy-factory PROXY_FACTORY] [--callback-handler CALLBACK_HANDLER] [--salt-nonce SALT_NONCE] [--without-events] [--only-generate] node_url private_key

Example:
safe-creator https://sepolia.drpc.org 0000000000000000000000000000000000000000000000000000000000000000
Expand All @@ -53,6 +53,12 @@ def setup_argument_parser():
parser.add_argument(
"private_key", help="Deployer private_key", type=check_private_key
)
parser.add_argument(
"--quiet",
help="Limit output to only prompts, errors, and the address of the created Safe",
default=False,
action="store_true",
)
parser.add_argument(
"--threshold",
help="Number of owners required to execute transactions on the created Safe. It must"
Expand Down Expand Up @@ -92,20 +98,24 @@ def setup_argument_parser():
default=secrets.randbits(256),
type=int,
)

parser.add_argument(
"--without-events",
help="Use non events deployment of the Safe instead of the regular one. Recommended for mainnet to save gas costs when using the Safe",
default=False,
action="store_true",
)
parser.add_argument(
"--dry-run",
help="Only generate the projected Safe address, do not actually create it",
default=False,
action="store_true",
)
return parser


def main(*args, **kwargs) -> EthereumTxSent:
parser = setup_argument_parser()
args = parser.parse_args()
print_formatted_text(text2art("Safe Creator")) # Print fancy text
node_url: URI = args.node_url
account: LocalAccount = Account.from_key(args.private_key)
owners: List[str] = args.owners if args.owners else [account.address]
Expand All @@ -117,9 +127,12 @@ def main(*args, **kwargs) -> EthereumTxSent:
payment = 0
payment_receiver = NULL_ADDRESS

if not args.quiet:
print_formatted_text(text2art("Safe Creator")) # Print fancy text

if len(owners) < threshold:
print_formatted_text(
"Threshold cannot be bigger than the number of unique owners"
f"Threshold cannot be bigger than the number of unique owners ({len(owners)})"
)
sys.exit(1)

Expand Down Expand Up @@ -159,36 +172,40 @@ def main(*args, **kwargs) -> EthereumTxSent:
)
sys.exit(1)

account_balance: int = ethereum_client.get_balance(account.address)
if not account_balance:
print_formatted_text(
"Client does not have any funds. Let's try anyway in case it's a network without gas costs"
)
else:
ether_account_balance = round(
ethereum_client.w3.from_wei(account_balance, "ether"), 6
)
print_formatted_text(
f"Network {ethereum_client.get_network().name} - Sender {account.address} - "
f"Balance: {ether_account_balance}Ξ"
)
if not args.dry_run:
account_balance: int = ethereum_client.get_balance(account.address)
if not account_balance:
print_formatted_text(
"Client does not have any funds. Let's try anyway in case it's a network without gas costs"
)
else:
ether_account_balance = round(
ethereum_client.w3.from_wei(account_balance, "ether"), 6
)
if not args.quiet:
print_formatted_text(
f"Network {ethereum_client.get_network().name} - Sender {account.address} - "
f"Balance: {ether_account_balance}Ξ"
)

if not ethereum_client.w3.eth.get_code(
safe_contract_address
) or not ethereum_client.w3.eth.get_code(proxy_factory_address):
print_formatted_text("Network not supported")
sys.exit(1)

print_formatted_text(
f"Creating new Safe with owners={owners} threshold={threshold} salt-nonce={salt_nonce}"
)
if not args.quiet:
print_formatted_text(
f"Creating new Safe with owners={owners} threshold={threshold} salt-nonce={salt_nonce}"
)
safe_version = Safe(safe_contract_address, ethereum_client).retrieve_version()
print_formatted_text(
f"Safe-master-copy={safe_contract_address} version={safe_version}\n"
f"Fallback-handler={fallback_handler}\n"
f"Proxy factory={proxy_factory_address}"
)
if yes_or_no_question("Do you want to continue?"):
if not args.quiet:
print_formatted_text(
f"Safe-master-copy={safe_contract_address} version={safe_version}\n"
f"Fallback-handler={fallback_handler}\n"
f"Proxy factory={proxy_factory_address}"
)
if args.dry_run or yes_or_no_question("Do you want to continue?"):
safe_contract = get_safe_V1_4_1_contract(
ethereum_client.w3, safe_contract_address
)
Expand All @@ -213,7 +230,13 @@ def main(*args, **kwargs) -> EthereumTxSent:
print_formatted_text(f"Safe on {expected_safe_address} is already deployed")
sys.exit(1)

if yes_or_no_question(
if args.dry_run:
if args.quiet:
print_formatted_text(expected_safe_address)
else:
print_formatted_text(f"Safe will be deployed on {expected_safe_address}")
sys.exit(0)
elif yes_or_no_question(
f"Safe will be deployed on {expected_safe_address}, looks good?"
):
ethereum_tx_sent = proxy_factory.deploy_proxy_contract_with_nonce(
Expand Down
Loading