diff --git a/crates/cast/bin/opts.rs b/crates/cast/bin/opts.rs index fa649b715dec..b763821fa06d 100644 --- a/crates/cast/bin/opts.rs +++ b/crates/cast/bin/opts.rs @@ -8,7 +8,6 @@ use clap::{Parser, Subcommand, ValueHint}; use ethers_core::types::{BlockId, NameOrAddress}; use eyre::Result; use foundry_cli::opts::{EtherscanOpts, RpcOpts}; -use foundry_common::serde_helpers::Numeric; use std::{path::PathBuf, str::FromStr}; const VERSION_MESSAGE: &str = concat!( @@ -874,8 +873,7 @@ pub struct ToBaseArgs { } pub fn parse_slot(s: &str) -> Result { - let slot = Numeric::from_str(s).map_err(|e| eyre::eyre!("Could not parse slot number: {e}"))?; - let slot: U256 = slot.into(); + let slot = U256::from_str(s).map_err(|e| eyre::eyre!("Could not parse slot number: {e}"))?; Ok(B256::from(slot)) } diff --git a/crates/cast/tests/cli/main.rs b/crates/cast/tests/cli/main.rs index 238e5d76747b..5801b7d43ffa 100644 --- a/crates/cast/tests/cli/main.rs +++ b/crates/cast/tests/cli/main.rs @@ -72,7 +72,7 @@ casttest!(wallet_address_keystore_with_password_file, |_prj, cmd| { }); // tests that `cast wallet sign message` outputs the expected signature -casttest!(cast_wallet_sign_message_utf8_data, |_prj, cmd| { +casttest!(wallet_sign_message_utf8_data, |_prj, cmd| { cmd.args([ "wallet", "sign", @@ -85,7 +85,7 @@ casttest!(cast_wallet_sign_message_utf8_data, |_prj, cmd| { }); // tests that `cast wallet sign message` outputs the expected signature, given a 0x-prefixed data -casttest!(cast_wallet_sign_message_hex_data, |_prj, cmd| { +casttest!(wallet_sign_message_hex_data, |_prj, cmd| { cmd.args([ "wallet", "sign", @@ -98,7 +98,7 @@ casttest!(cast_wallet_sign_message_hex_data, |_prj, cmd| { }); // tests that `cast wallet sign typed-data` outputs the expected signature, given a JSON string -casttest!(cast_wallet_sign_typed_data_string, |_prj, cmd| { +casttest!(wallet_sign_typed_data_string, |_prj, cmd| { cmd.args([ "wallet", "sign", @@ -112,7 +112,7 @@ casttest!(cast_wallet_sign_typed_data_string, |_prj, cmd| { }); // tests that `cast wallet sign typed-data` outputs the expected signature, given a JSON file -casttest!(cast_wallet_sign_typed_data_file, |_prj, cmd| { +casttest!(wallet_sign_typed_data_file, |_prj, cmd| { cmd.args([ "wallet", "sign", @@ -219,7 +219,7 @@ casttest!(upload_signatures, |_prj, cmd| { }); // tests that the `cast to-rlp` and `cast from-rlp` commands work correctly -casttest!(cast_rlp, |_prj, cmd| { +casttest!(rlp, |_prj, cmd| { cmd.args(["--to-rlp", "[\"0xaa\", [[\"bb\"]], \"0xcc\"]"]); let out = cmd.stdout_lossy(); assert!(out.contains("0xc881aac3c281bb81cc"), "{}", out); @@ -231,7 +231,7 @@ casttest!(cast_rlp, |_prj, cmd| { }); // test for cast_rpc without arguments -casttest!(cast_rpc_no_args, |_prj, cmd| { +casttest!(rpc_no_args, |_prj, cmd| { let eth_rpc_url = next_http_rpc_endpoint(); // Call `cast rpc eth_chainId` @@ -241,7 +241,7 @@ casttest!(cast_rpc_no_args, |_prj, cmd| { }); // test for cast_rpc without arguments using websocket -casttest!(cast_ws_rpc_no_args, |_prj, cmd| { +casttest!(ws_rpc_no_args, |_prj, cmd| { let eth_rpc_url = next_ws_rpc_endpoint(); // Call `cast rpc eth_chainId` @@ -251,7 +251,7 @@ casttest!(cast_ws_rpc_no_args, |_prj, cmd| { }); // test for cast_rpc with arguments -casttest!(cast_rpc_with_args, |_prj, cmd| { +casttest!(rpc_with_args, |_prj, cmd| { let eth_rpc_url = next_http_rpc_endpoint(); // Call `cast rpc eth_getBlockByNumber 0x123 false` @@ -261,7 +261,7 @@ casttest!(cast_rpc_with_args, |_prj, cmd| { }); // test for cast_rpc with raw params -casttest!(cast_rpc_raw_params, |_prj, cmd| { +casttest!(rpc_raw_params, |_prj, cmd| { let eth_rpc_url = next_http_rpc_endpoint(); // Call `cast rpc eth_getBlockByNumber --raw '["0x123", false]'` @@ -278,7 +278,7 @@ casttest!(cast_rpc_raw_params, |_prj, cmd| { }); // test for cast_rpc with direct params -casttest!(cast_rpc_raw_params_stdin, |_prj, cmd| { +casttest!(rpc_raw_params_stdin, |_prj, cmd| { let eth_rpc_url = next_http_rpc_endpoint(); // Call `echo "\n[\n\"0x123\",\nfalse\n]\n" | cast rpc eth_getBlockByNumber --raw @@ -300,7 +300,7 @@ casttest!(calldata_array, |_prj, cmd| { }); // -casttest!(cast_run_succeeds, |_prj, cmd| { +casttest!(run_succeeds, |_prj, cmd| { let rpc = next_http_rpc_endpoint(); cmd.args([ "run", @@ -316,7 +316,7 @@ casttest!(cast_run_succeeds, |_prj, cmd| { }); // tests that `cast --to-base` commands are working correctly. -casttest!(cast_to_base, |_prj, cmd| { +casttest!(to_base, |_prj, cmd| { let values = [ "1", "100", @@ -344,7 +344,7 @@ casttest!(cast_to_base, |_prj, cmd| { }); // tests that revert reason is only present if transaction has reverted. -casttest!(cast_receipt_revert_reason, |_prj, cmd| { +casttest!(receipt_revert_reason, |_prj, cmd| { let rpc = next_http_rpc_endpoint(); // @@ -379,7 +379,7 @@ casttest!(parse_bytes32_address, |_prj, cmd| { assert_eq!(output.trim(), "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045") }); -casttest!(cast_access_list, |_prj, cmd| { +casttest!(access_list, |_prj, cmd| { let rpc = next_http_rpc_endpoint(); cmd.args([ "access-list", @@ -398,7 +398,7 @@ casttest!(cast_access_list, |_prj, cmd| { assert!(output.contains("0x7fba2702a7d6e85ac783a88eacdc48e51310443458071f6db9ac66f8ca7068b8")); }); -casttest!(cast_logs_topics, |_prj, cmd| { +casttest!(logs_topics, |_prj, cmd| { let rpc = next_http_rpc_endpoint(); cmd.args([ "logs", @@ -417,7 +417,7 @@ casttest!(cast_logs_topics, |_prj, cmd| { ); }); -casttest!(cast_logs_topic_2, |_prj, cmd| { +casttest!(logs_topic_2, |_prj, cmd| { let rpc = next_http_rpc_endpoint(); cmd.args([ "logs", @@ -438,7 +438,7 @@ casttest!(cast_logs_topic_2, |_prj, cmd| { ); }); -casttest!(cast_logs_sig, |_prj, cmd| { +casttest!(logs_sig, |_prj, cmd| { let rpc = next_http_rpc_endpoint(); cmd.args([ "logs", @@ -457,7 +457,7 @@ casttest!(cast_logs_sig, |_prj, cmd| { ); }); -casttest!(cast_logs_sig_2, |_prj, cmd| { +casttest!(logs_sig_2, |_prj, cmd| { let rpc = next_http_rpc_endpoint(); cmd.args([ "logs", @@ -478,7 +478,7 @@ casttest!(cast_logs_sig_2, |_prj, cmd| { }); // tests that the raw encoded transaction is returned -casttest!(cast_tx_raw, |_prj, cmd| { +casttest!(tx_raw, |_prj, cmd| { let rpc = next_http_rpc_endpoint(); // @@ -509,7 +509,7 @@ casttest!(cast_tx_raw, |_prj, cmd| { }); // ensure receipt or code is required -casttest!(cast_send_requires_to, |_prj, cmd| { +casttest!(send_requires_to, |_prj, cmd| { cmd.args([ "send", "--private-key", @@ -521,3 +521,22 @@ casttest!(cast_send_requires_to, |_prj, cmd| { "Error: \nMust specify a recipient address or contract code to deploy" ); }); + +casttest!(storage, |_prj, cmd| { + let empty = "0x0000000000000000000000000000000000000000000000000000000000000000"; + + let rpc = next_http_rpc_endpoint(); + cmd.cast_fuse().args(["storage", "vitalik.eth", "1", "--rpc-url", &rpc]); + assert_eq!(cmd.stdout_lossy().trim(), empty); + + let rpc = next_http_rpc_endpoint(); + cmd.cast_fuse().args(["storage", "vitalik.eth", "0x01", "--rpc-url", &rpc]); + assert_eq!(cmd.stdout_lossy().trim(), empty); + + let rpc = next_http_rpc_endpoint(); + let usdt = "0xdac17f958d2ee523a2206206994597c13d831ec7"; + let decimals_slot = "0x09"; + let six = "0x0000000000000000000000000000000000000000000000000000000000000006"; + cmd.cast_fuse().args(["storage", usdt, decimals_slot, "--rpc-url", &rpc]); + assert_eq!(cmd.stdout_lossy().trim(), six); +}); diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 241041ee8160..584a3638981d 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -19,7 +19,6 @@ pub mod glob; pub mod provider; pub mod runtime_client; pub mod selectors; -pub mod serde_helpers; pub mod shell; pub mod term; pub mod traits; diff --git a/crates/common/src/serde_helpers.rs b/crates/common/src/serde_helpers.rs deleted file mode 100644 index 8d8788561f6a..000000000000 --- a/crates/common/src/serde_helpers.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! Misc Serde helpers for foundry crates. - -use alloy_primitives::U256; -use serde::Deserialize; -use std::str::FromStr; - -/// Helper type to parse both `u64` and `U256` -#[derive(Copy, Clone, Deserialize)] -#[serde(untagged)] -pub enum Numeric { - /// A [U256] value. - U256(U256), - /// A `u64` value. - Num(u64), -} - -impl From for U256 { - fn from(n: Numeric) -> U256 { - match n { - Numeric::U256(n) => n, - Numeric::Num(n) => U256::from(n), - } - } -} - -impl FromStr for Numeric { - type Err = String; - - fn from_str(s: &str) -> Result { - if let Ok(val) = s.parse::() { - Ok(Numeric::U256(U256::from(val))) - } else if s.starts_with("0x") { - U256::from_str_radix(s, 16).map(Numeric::U256).map_err(|err| err.to_string()) - } else { - U256::from_str(s).map(Numeric::U256).map_err(|err| err.to_string()) - } - } -}