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

feat: add inputs argument #12

Merged
merged 6 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
18 changes: 18 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ struct Args {
/// Only output the transaction calldata without any extra information.
#[arg(short, long)]
quiet: bool,

/// Quiet mode.
///
/// Only output the transaction calldata without any extra information.
#[arg(short, long)]
inputs: bool,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked your suggestion of calling this params to print out the createProxyWithNonce parameters.

The issue with it not working with the existing prefix flag is that #[arg(short)] defaults to using the first letter of there field name. You can fix that by specifying something else, for example:

Suggested change
#[arg(short, long)]
inputs: bool,
#[arg(short = 'P', long)]
params: bool,

This way, -P is used to print parameters, and -p is used for setting a prefix.

}

/// Helper type for parsing hexadecimal byte input from the command line.
Expand Down Expand Up @@ -108,9 +114,20 @@ fn main() {

let safe = receiver.recv().expect("missing result");
let transaction = safe.transaction();
let initializer_hex = hex::encode(safe.initializer());

if args.quiet {
println!("0x{}", hex::encode(&transaction.calldata));
} else if args.inputs {
println!("address: {}", safe.creation_address());
println!("owners: {}", args.owners[0]);
for owner in &args.owners[1..] {
println!(" {}", owner);
}
println!("--------------------------------------------------------");
println!("_singleton: {}", contracts.singleton);
println!("initializer: 0x{}", initializer_hex);
println!("saltNonce: 0x{}", hex::encode(&safe.salt_nonce()));
} else {
println!("address: {}", safe.creation_address());
println!("factory: {}", contracts.proxy_factory);
Expand All @@ -122,6 +139,7 @@ fn main() {
}
println!("threshold: {}", args.threshold);
println!("calldata: 0x{}", hex::encode(&transaction.calldata));

}

let _ = threads;
Expand Down
18 changes: 16 additions & 2 deletions core/src/safe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct Safe {
threshold: usize,
salt: [u8; 64],
create2: Create2,
initializer_calldata: Vec<u8>,
}

/// Safe contract data on a given chain.
Expand Down Expand Up @@ -39,17 +40,23 @@ pub struct Transaction {
impl Safe {
/// Creates a new safe from deployment parameters.
pub fn new(contracts: Contracts, owners: Vec<Address>, threshold: usize) -> Self {
// Compute the initializer calldata once and store it
let initializer_calldata = contracts.initializer(&owners, threshold);

// Compute the salt using the initializer calldata
let mut salt = [0_u8; 64];
let mut hasher = Keccak::v256();
hasher.update(&contracts.initializer(&owners, threshold));
hasher.update(&initializer_calldata);
hasher.finalize(&mut salt[0..32]);

let mut create2 = Create2::new(
contracts.proxy_factory,
Default::default(),
contracts.proxy_init_code_digest(),
);
let mut hasher = Keccak::v256();

// Update the salt for the create2 instance
hasher = Keccak::v256();
hasher.update(&salt);
hasher.finalize(create2.salt_mut());

Expand All @@ -59,6 +66,7 @@ impl Safe {
threshold,
salt,
create2,
initializer_calldata, // Store the initializer data here
}
}

Expand All @@ -72,6 +80,11 @@ impl Safe {
self.salt[32..64].try_into().unwrap()
}

/// Returns the initializer calldata for the Safe.
pub fn initializer(&self) -> &[u8] {
&self.initializer_calldata
}

/// Updates the salt nonce and recomputes the `CREATE2` salt.
pub fn update_salt_nonce(&mut self, f: impl FnOnce(&mut [u8])) {
let salt_nonce = unsafe { self.salt.get_unchecked_mut(32..64) };
Expand Down Expand Up @@ -147,6 +160,7 @@ impl Contracts {
buffer.extend_from_slice(&[0_u8; 28]); // padding
buffer
}

}

/// Poor man's ABI encode.
Expand Down