Skip to content

Commit

Permalink
Merge branch 'master' into cast-storage-re
Browse files Browse the repository at this point in the history
  • Loading branch information
grandizzy committed Nov 27, 2024
2 parents 0e11203 + 31dd1f7 commit 44fbe73
Show file tree
Hide file tree
Showing 21 changed files with 378 additions and 152 deletions.
21 changes: 15 additions & 6 deletions crates/cast/bin/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,8 @@ pub enum CastSubcommand {
///
/// Similar to `abi-decode --input`, but function selector MUST be prefixed in `calldata`
/// string
#[command(visible_aliases = &["--calldata-decode", "cdd"])]
CalldataDecode {
#[command(visible_aliases = &["calldata-decode", "--calldata-decode", "cdd"])]
DecodeCalldata {
/// The function signature in the format `<name>(<in-types>)(<out-types>)`.
sig: String,

Expand All @@ -524,19 +524,28 @@ pub enum CastSubcommand {
/// Decode ABI-encoded string.
///
/// Similar to `calldata-decode --input`, but the function argument is a `string`
#[command(visible_aliases = &["--string-decode", "sd"])]
StringDecode {
#[command(visible_aliases = &["string-decode", "--string-decode", "sd"])]
DecodeString {
/// The ABI-encoded string.
data: String,
},

/// Decode event data.
#[command(visible_aliases = &["event-decode", "--event-decode", "ed"])]
DecodeEvent {
/// The event signature.
sig: String,
/// The event data to decode.
data: String,
},

/// Decode ABI-encoded input or output data.
///
/// Defaults to decoding output data. To decode input data pass --input.
///
/// When passing `--input`, function selector must NOT be prefixed in `calldata` string
#[command(name = "abi-decode", visible_aliases = &["ad", "--abi-decode"])]
AbiDecode {
#[command(name = "decode-abi", visible_aliases = &["abi-decode", "--abi-decode", "ad"])]
DecodeAbi {
/// The function signature in the format `<name>(<in-types>)(<out-types>)`.
sig: String,

Expand Down
13 changes: 9 additions & 4 deletions crates/cast/bin/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[macro_use]
extern crate tracing;

use alloy_dyn_abi::DynSolValue;
use alloy_dyn_abi::{DynSolValue, EventExt};
use alloy_primitives::{eip191_hash_message, hex, keccak256, Address, B256};
use alloy_provider::Provider;
use alloy_rpc_types::{BlockId, BlockNumberOrTag::Latest};
Expand Down Expand Up @@ -189,7 +189,7 @@ async fn main_args(args: CastArgs) -> Result<()> {
}

// ABI encoding & decoding
CastSubcommand::AbiDecode { sig, calldata, input } => {
CastSubcommand::DecodeAbi { sig, calldata, input } => {
let tokens = SimpleCast::abi_decode(&sig, &calldata, input)?;
print_tokens(&tokens);
}
Expand All @@ -200,17 +200,22 @@ async fn main_args(args: CastArgs) -> Result<()> {
sh_println!("{}", SimpleCast::abi_encode_packed(&sig, &args)?)?
}
}
CastSubcommand::CalldataDecode { sig, calldata } => {
CastSubcommand::DecodeCalldata { sig, calldata } => {
let tokens = SimpleCast::calldata_decode(&sig, &calldata, true)?;
print_tokens(&tokens);
}
CastSubcommand::CalldataEncode { sig, args } => {
sh_println!("{}", SimpleCast::calldata_encode(sig, &args)?)?;
}
CastSubcommand::StringDecode { data } => {
CastSubcommand::DecodeString { data } => {
let tokens = SimpleCast::calldata_decode("Any(string)", &data, true)?;
print_tokens(&tokens);
}
CastSubcommand::DecodeEvent { sig, data } => {
let event = get_event(sig.as_str())?;
let decoded_event = event.decode_log_parts(None, &hex::decode(data)?, false)?;
print_tokens(&decoded_event.body);
}
CastSubcommand::Interface(cmd) => cmd.run().await?,
CastSubcommand::CreationCode(cmd) => cmd.run().await?,
CastSubcommand::ConstructorArgs(cmd) => cmd.run().await?,
Expand Down
21 changes: 20 additions & 1 deletion crates/cast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2017,7 +2017,7 @@ impl SimpleCast {
pub fn disassemble(code: &[u8]) -> Result<String> {
let mut output = String::new();

for step in decode_instructions(code) {
for step in decode_instructions(code)? {
write!(output, "{:08x}: ", step.pc)?;

if let Some(op) = step.op {
Expand Down Expand Up @@ -2290,4 +2290,23 @@ mod tests {
r#"["0x2b5df5f0757397573e8ff34a8b987b21680357de1f6c8d10273aa528a851eaca","0x","0x","0x2838ac1d2d2721ba883169179b48480b2ba4f43d70fcf806956746bd9e83f903","0x","0xe46fff283b0ab96a32a7cc375cecc3ed7b6303a43d64e0a12eceb0bc6bd87549","0x","0x1d818c1c414c665a9c9a0e0c0ef1ef87cacb380b8c1f6223cb2a68a4b2d023f5","0x","0x","0x","0x236e8f61ecde6abfebc6c529441f782f62469d8a2cc47b7aace2c136bd3b1ff0","0x","0x","0x","0x","0x"]"#
)
}

#[test]
fn disassemble_incomplete_sequence() {
let incomplete = &hex!("60"); // PUSH1
let disassembled = Cast::disassemble(incomplete);
assert!(disassembled.is_err());

let complete = &hex!("6000"); // PUSH1 0x00
let disassembled = Cast::disassemble(complete);
assert!(disassembled.is_ok());

let incomplete = &hex!("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // PUSH32 with 31 bytes
let disassembled = Cast::disassemble(incomplete);
assert!(disassembled.is_err());

let complete = &hex!("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // PUSH32 with 32 bytes
let disassembled = Cast::disassemble(complete);
assert!(disassembled.is_ok());
}
}
8 changes: 8 additions & 0 deletions crates/cast/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,14 @@ casttest!(string_decode, |_prj, cmd| {
"#]]);
});

casttest!(event_decode, |_prj, cmd| {
cmd.args(["decode-event", "MyEvent(uint256,address)", "0x000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000d0004f"]).assert_success().stdout_eq(str![[r#"
78
0x0000000000000000000000000000000000D0004F
"#]]);
});

casttest!(format_units, |_prj, cmd| {
cmd.args(["format-units", "1000000", "6"]).assert_success().stdout_eq(str![[r#"
1
Expand Down
20 changes: 10 additions & 10 deletions crates/cheatcodes/assets/cheatcodes.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions crates/cheatcodes/spec/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ interface Vm {

/// Gets all the logs according to specified filter.
#[cheatcode(group = Evm, safety = Safe)]
function eth_getLogs(uint256 fromBlock, uint256 toBlock, address target, bytes32[] memory topics)
function eth_getLogs(uint256 fromBlock, uint256 toBlock, address target, bytes32[] calldata topics)
external
returns (EthGetLogs[] memory logs);

Expand Down Expand Up @@ -1764,35 +1764,35 @@ interface Vm {
///
/// The most recent call can be fetched by passing `txType` as `CALL`.
#[cheatcode(group = Filesystem)]
function getBroadcast(string memory contractName, uint64 chainId, BroadcastTxType txType) external view returns (BroadcastTxSummary memory);
function getBroadcast(string calldata contractName, uint64 chainId, BroadcastTxType txType) external view returns (BroadcastTxSummary memory);

/// Returns all broadcasts for the given contract on `chainId` with the specified `txType`.
///
/// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber.
#[cheatcode(group = Filesystem)]
function getBroadcasts(string memory contractName, uint64 chainId, BroadcastTxType txType) external view returns (BroadcastTxSummary[] memory);
function getBroadcasts(string calldata contractName, uint64 chainId, BroadcastTxType txType) external view returns (BroadcastTxSummary[] memory);

/// Returns all broadcasts for the given contract on `chainId`.
///
/// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber.
#[cheatcode(group = Filesystem)]
function getBroadcasts(string memory contractName, uint64 chainId) external view returns (BroadcastTxSummary[] memory);
function getBroadcasts(string calldata contractName, uint64 chainId) external view returns (BroadcastTxSummary[] memory);

/// Returns the most recent deployment for the current `chainId`.
#[cheatcode(group = Filesystem)]
function getDeployment(string memory contractName) external view returns (address deployedAddress);
function getDeployment(string calldata contractName) external view returns (address deployedAddress);

/// Returns the most recent deployment for the given contract on `chainId`
#[cheatcode(group = Filesystem)]
function getDeployment(string memory contractName, uint64 chainId) external view returns (address deployedAddress);
function getDeployment(string calldata contractName, uint64 chainId) external view returns (address deployedAddress);

/// Returns all deployments for the given contract on `chainId`
///
/// Sorted in descending order of deployment time i.e descending order of BroadcastTxSummary.blockNumber.
///
/// The most recent deployment is the first element, and the oldest is the last.
#[cheatcode(group = Filesystem)]
function getDeployments(string memory contractName, uint64 chainId) external view returns (address[] memory deployedAddresses);
function getDeployments(string calldata contractName, uint64 chainId) external view returns (address[] memory deployedAddresses);

// -------- Foreign Function Interface --------

Expand Down Expand Up @@ -2040,7 +2040,7 @@ interface Vm {

/// Designate the next call as an EIP-7702 transaction
#[cheatcode(group = Scripting)]
function attachDelegation(SignedDelegation memory signedDelegation) external;
function attachDelegation(SignedDelegation calldata signedDelegation) external;

/// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction
#[cheatcode(group = Scripting)]
Expand Down Expand Up @@ -2298,13 +2298,13 @@ interface Vm {
returns (string memory json);
/// See `serializeJson`.
#[cheatcode(group = Json)]
function serializeJsonType(string calldata typeDescription, bytes memory value)
function serializeJsonType(string calldata typeDescription, bytes calldata value)
external
pure
returns (string memory json);
/// See `serializeJson`.
#[cheatcode(group = Json)]
function serializeJsonType(string calldata objectKey, string calldata valueKey, string calldata typeDescription, bytes memory value)
function serializeJsonType(string calldata objectKey, string calldata valueKey, string calldata typeDescription, bytes calldata value)
external
returns (string memory json);

Expand Down
7 changes: 1 addition & 6 deletions crates/common/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,6 @@ impl Provider for EvmArgs {
#[derive(Clone, Debug, Default, Serialize, Parser)]
#[command(next_help_heading = "Executor environment config")]
pub struct EnvArgs {
/// The block gas limit.
#[arg(long, value_name = "GAS_LIMIT")]
#[serde(skip_serializing_if = "Option::is_none")]
pub gas_limit: Option<u64>,

/// EIP-170: Contract code size limit in bytes. Useful to increase this because of tests. By
/// default, it is 0x6000 (~25kb).
#[arg(long, value_name = "CODE_SIZE")]
Expand Down Expand Up @@ -253,7 +248,7 @@ pub struct EnvArgs {
pub block_prevrandao: Option<B256>,

/// The block gas limit.
#[arg(long, value_name = "GAS_LIMIT")]
#[arg(long, visible_alias = "gas-limit", value_name = "GAS_LIMIT")]
#[serde(skip_serializing_if = "Option::is_none")]
pub block_gas_limit: Option<u64>,

Expand Down
9 changes: 7 additions & 2 deletions crates/evm/core/src/ic.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use alloy_primitives::map::HashMap;
use eyre::Result;
use revm::interpreter::{
opcode::{PUSH0, PUSH1, PUSH32},
OpCode,
Expand Down Expand Up @@ -100,18 +101,22 @@ pub struct Instruction<'a> {
}

/// Decodes raw opcode bytes into [`Instruction`]s.
pub fn decode_instructions(code: &[u8]) -> Vec<Instruction<'_>> {
pub fn decode_instructions(code: &[u8]) -> Result<Vec<Instruction<'_>>> {
let mut pc = 0;
let mut steps = Vec::new();

while pc < code.len() {
let op = OpCode::new(code[pc]);
let immediate_size = op.map(|op| immediate_size(op, &code[pc + 1..])).unwrap_or(0) as usize;

if pc + 1 + immediate_size > code.len() {
eyre::bail!("incomplete sequence of bytecode");
}

steps.push(Instruction { op, pc, immediate: &code[pc + 1..pc + 1 + immediate_size] });

pc += 1 + immediate_size;
}

steps
Ok(steps)
}
10 changes: 9 additions & 1 deletion crates/forge/bin/cmd/create.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::cmd::install;
use alloy_chains::Chain;
use alloy_dyn_abi::{DynSolValue, JsonAbiExt, Specifier};
use alloy_json_abi::{Constructor, JsonAbi};
Expand Down Expand Up @@ -98,7 +99,14 @@ pub struct CreateArgs {
impl CreateArgs {
/// Executes the command to create a contract
pub async fn run(mut self) -> Result<()> {
let config = self.try_load_config_emit_warnings()?;
let mut config = self.try_load_config_emit_warnings()?;

// Install missing dependencies.
if install::install_missing_dependencies(&mut config) && config.auto_detect_remappings {
// need to re-configure here to also catch additional remappings
config = self.load_config();
}

// Find Project & Compile
let project = config.project()?;

Expand Down
Loading

0 comments on commit 44fbe73

Please sign in to comment.