cast/
lib.rs

1//! Cast is a Swiss Army knife for interacting with Ethereum applications from the command line.
2
3#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
4#![cfg_attr(not(test), warn(unused_crate_dependencies))]
5
6use alloy_consensus::TxEnvelope;
7use alloy_dyn_abi::{DynSolType, DynSolValue, FunctionExt};
8use alloy_ens::NameOrAddress;
9use alloy_json_abi::Function;
10use alloy_network::{AnyNetwork, AnyRpcTransaction};
11use alloy_primitives::{
12    hex,
13    utils::{keccak256, ParseUnits, Unit},
14    Address, Keccak256, Selector, TxHash, TxKind, B256, I256, U256, U64,
15};
16use alloy_provider::{
17    network::eip2718::{Decodable2718, Encodable2718},
18    PendingTransactionBuilder, Provider,
19};
20use alloy_rlp::Decodable;
21use alloy_rpc_types::{
22    state::StateOverride, BlockId, BlockNumberOrTag, Filter, TransactionRequest,
23};
24use alloy_serde::WithOtherFields;
25use alloy_sol_types::sol;
26use base::{Base, NumberWithBase, ToBase};
27use chrono::DateTime;
28use eyre::{Context, ContextCompat, OptionExt, Result};
29use foundry_block_explorers::Client;
30use foundry_common::{
31    abi::{encode_function_args, get_func},
32    compile::etherscan_project,
33    fmt::*,
34    fs, get_pretty_tx_receipt_attr, shell, TransactionReceiptWithRevertReason,
35};
36use foundry_compilers::flatten::Flattener;
37use foundry_config::Chain;
38use foundry_evm_core::ic::decode_instructions;
39use futures::{future::Either, FutureExt, StreamExt};
40use op_alloy_consensus::OpTxEnvelope;
41use rayon::prelude::*;
42use std::{
43    borrow::Cow,
44    fmt::Write,
45    io,
46    path::PathBuf,
47    str::FromStr,
48    sync::atomic::{AtomicBool, Ordering},
49    time::Duration,
50};
51use tokio::signal::ctrl_c;
52
53use foundry_common::abi::encode_function_args_packed;
54pub use foundry_evm::*;
55
56pub mod args;
57pub mod cmd;
58pub mod opts;
59
60pub mod base;
61pub mod errors;
62mod rlp_converter;
63pub mod tx;
64
65use rlp_converter::Item;
66
67#[macro_use]
68extern crate tracing;
69
70#[macro_use]
71extern crate foundry_common;
72
73// TODO: CastContract with common contract initializers? Same for CastProviders?
74
75sol! {
76    #[sol(rpc)]
77    interface IERC20 {
78        #[derive(Debug)]
79        function balanceOf(address owner) external view returns (uint256);
80    }
81}
82
83pub struct Cast<P> {
84    provider: P,
85}
86
87impl<P: Provider<AnyNetwork>> Cast<P> {
88    /// Creates a new Cast instance from the provided client
89    ///
90    /// # Example
91    ///
92    /// ```
93    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
94    /// use cast::Cast;
95    ///
96    /// # async fn foo() -> eyre::Result<()> {
97    /// let provider =
98    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
99    /// let cast = Cast::new(provider);
100    /// # Ok(())
101    /// # }
102    /// ```
103    pub fn new(provider: P) -> Self {
104        Self { provider }
105    }
106
107    /// Makes a read-only call to the specified address
108    ///
109    /// # Example
110    ///
111    /// ```
112    /// use alloy_primitives::{Address, U256, Bytes};
113    /// use alloy_rpc_types::{TransactionRequest, state::{StateOverride, AccountOverride}};
114    /// use alloy_serde::WithOtherFields;
115    /// use cast::Cast;
116    /// use alloy_provider::{RootProvider, ProviderBuilder, network::AnyNetwork};
117    /// use std::{str::FromStr, collections::HashMap};
118    /// use alloy_rpc_types::state::StateOverridesBuilder;
119    /// use alloy_sol_types::{sol, SolCall};
120    ///
121    /// sol!(
122    ///     function greeting(uint256 i) public returns (string);
123    /// );
124    ///
125    /// # async fn foo() -> eyre::Result<()> {
126    /// let alloy_provider = ProviderBuilder::<_,_, AnyNetwork>::default().connect("http://localhost:8545").await?;;
127    /// let to = Address::from_str("0xB3C95ff08316fb2F2e3E52Ee82F8e7b605Aa1304")?;
128    /// let greeting = greetingCall { i: U256::from(5) }.abi_encode();
129    /// let bytes = Bytes::from_iter(greeting.iter());
130    /// let tx = TransactionRequest::default().to(to).input(bytes.into());
131    /// let tx = WithOtherFields::new(tx);
132    ///
133    /// // Create state overrides
134    /// let mut state_override = StateOverride::default();
135    /// let mut account_override = AccountOverride::default();
136    /// account_override.balance = Some(U256::from(1000));
137    /// state_override.insert(to, account_override);
138    /// let state_override_object = StateOverridesBuilder::default().build();
139    ///
140    /// let cast = Cast::new(alloy_provider);
141    /// let data = cast.call(&tx, None, None, Some(state_override_object)).await?;
142    /// println!("{}", data);
143    /// # Ok(())
144    /// # }
145    /// ```
146    pub async fn call(
147        &self,
148        req: &WithOtherFields<TransactionRequest>,
149        func: Option<&Function>,
150        block: Option<BlockId>,
151        state_override: Option<StateOverride>,
152    ) -> Result<String> {
153        let mut call = self.provider.call(req.clone()).block(block.unwrap_or_default());
154        if let Some(state_override) = state_override {
155            call = call.overrides(state_override)
156        }
157
158        let res = call.await?;
159        let mut decoded = vec![];
160
161        if let Some(func) = func {
162            // decode args into tokens
163            decoded = match func.abi_decode_output(res.as_ref()) {
164                Ok(decoded) => decoded,
165                Err(err) => {
166                    // ensure the address is a contract
167                    if res.is_empty() {
168                        // check that the recipient is a contract that can be called
169                        if let Some(TxKind::Call(addr)) = req.to {
170                            if let Ok(code) = self
171                                .provider
172                                .get_code_at(addr)
173                                .block_id(block.unwrap_or_default())
174                                .await
175                            {
176                                if code.is_empty() {
177                                    eyre::bail!("contract {addr:?} does not have any code")
178                                }
179                            }
180                        } else if Some(TxKind::Create) == req.to {
181                            eyre::bail!("tx req is a contract deployment");
182                        } else {
183                            eyre::bail!("recipient is None");
184                        }
185                    }
186                    return Err(err).wrap_err(
187                        "could not decode output; did you specify the wrong function return data type?"
188                    );
189                }
190            };
191        }
192
193        // handle case when return type is not specified
194        Ok(if decoded.is_empty() {
195            res.to_string()
196        } else if shell::is_json() {
197            let tokens = decoded.iter().map(format_token_raw).collect::<Vec<_>>();
198            serde_json::to_string_pretty(&tokens).unwrap()
199        } else {
200            // seth compatible user-friendly return type conversions
201            decoded.iter().map(format_token).collect::<Vec<_>>().join("\n")
202        })
203    }
204
205    /// Generates an access list for the specified transaction
206    ///
207    /// # Example
208    ///
209    /// ```
210    /// use cast::{Cast};
211    /// use alloy_primitives::{Address, U256, Bytes};
212    /// use alloy_rpc_types::{TransactionRequest};
213    /// use alloy_serde::WithOtherFields;
214    /// use alloy_provider::{RootProvider, ProviderBuilder, network::AnyNetwork};
215    /// use std::str::FromStr;
216    /// use alloy_sol_types::{sol, SolCall};
217    ///
218    /// sol!(
219    ///     function greeting(uint256 i) public returns (string);
220    /// );
221    ///
222    /// # async fn foo() -> eyre::Result<()> {
223    /// let provider = ProviderBuilder::<_,_, AnyNetwork>::default().connect("http://localhost:8545").await?;;
224    /// let to = Address::from_str("0xB3C95ff08316fb2F2e3E52Ee82F8e7b605Aa1304")?;
225    /// let greeting = greetingCall { i: U256::from(5) }.abi_encode();
226    /// let bytes = Bytes::from_iter(greeting.iter());
227    /// let tx = TransactionRequest::default().to(to).input(bytes.into());
228    /// let tx = WithOtherFields::new(tx);
229    /// let cast = Cast::new(&provider);
230    /// let access_list = cast.access_list(&tx, None).await?;
231    /// println!("{}", access_list);
232    /// # Ok(())
233    /// # }
234    /// ```
235    pub async fn access_list(
236        &self,
237        req: &WithOtherFields<TransactionRequest>,
238        block: Option<BlockId>,
239    ) -> Result<String> {
240        let access_list =
241            self.provider.create_access_list(req).block_id(block.unwrap_or_default()).await?;
242        let res = if shell::is_json() {
243            serde_json::to_string(&access_list)?
244        } else {
245            let mut s =
246                vec![format!("gas used: {}", access_list.gas_used), "access list:".to_string()];
247            for al in access_list.access_list.0 {
248                s.push(format!("- address: {}", &al.address.to_checksum(None)));
249                if !al.storage_keys.is_empty() {
250                    s.push("  keys:".to_string());
251                    for key in al.storage_keys {
252                        s.push(format!("    {key:?}"));
253                    }
254                }
255            }
256            s.join("\n")
257        };
258
259        Ok(res)
260    }
261
262    pub async fn balance(&self, who: Address, block: Option<BlockId>) -> Result<U256> {
263        Ok(self.provider.get_balance(who).block_id(block.unwrap_or_default()).await?)
264    }
265
266    /// Sends a transaction to the specified address
267    ///
268    /// # Example
269    ///
270    /// ```
271    /// use cast::{Cast};
272    /// use alloy_primitives::{Address, U256, Bytes};
273    /// use alloy_serde::WithOtherFields;
274    /// use alloy_rpc_types::{TransactionRequest};
275    /// use alloy_provider::{RootProvider, ProviderBuilder, network::AnyNetwork};
276    /// use std::str::FromStr;
277    /// use alloy_sol_types::{sol, SolCall};
278    ///
279    /// sol!(
280    ///     function greet(string greeting) public;
281    /// );
282    ///
283    /// # async fn foo() -> eyre::Result<()> {
284    /// let provider = ProviderBuilder::<_,_, AnyNetwork>::default().connect("http://localhost:8545").await?;;
285    /// let from = Address::from_str("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")?;
286    /// let to = Address::from_str("0xB3C95ff08316fb2F2e3E52Ee82F8e7b605Aa1304")?;
287    /// let greeting = greetCall { greeting: "hello".to_string() }.abi_encode();
288    /// let bytes = Bytes::from_iter(greeting.iter());
289    /// let gas = U256::from_str("200000").unwrap();
290    /// let value = U256::from_str("1").unwrap();
291    /// let nonce = U256::from_str("1").unwrap();
292    /// let tx = TransactionRequest::default().to(to).input(bytes.into()).from(from);
293    /// let tx = WithOtherFields::new(tx);
294    /// let cast = Cast::new(provider);
295    /// let data = cast.send(tx).await?;
296    /// println!("{:#?}", data);
297    /// # Ok(())
298    /// # }
299    /// ```
300    pub async fn send(
301        &self,
302        tx: WithOtherFields<TransactionRequest>,
303    ) -> Result<PendingTransactionBuilder<AnyNetwork>> {
304        let res = self.provider.send_transaction(tx).await?;
305
306        Ok(res)
307    }
308
309    /// Publishes a raw transaction to the network
310    ///
311    /// # Example
312    ///
313    /// ```
314    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
315    /// use cast::Cast;
316    ///
317    /// # async fn foo() -> eyre::Result<()> {
318    /// let provider =
319    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
320    /// let cast = Cast::new(provider);
321    /// let res = cast.publish("0x1234".to_string()).await?;
322    /// println!("{:?}", res);
323    /// # Ok(())
324    /// # }
325    /// ```
326    pub async fn publish(
327        &self,
328        mut raw_tx: String,
329    ) -> Result<PendingTransactionBuilder<AnyNetwork>> {
330        raw_tx = match raw_tx.strip_prefix("0x") {
331            Some(s) => s.to_string(),
332            None => raw_tx,
333        };
334        let tx = hex::decode(raw_tx)?;
335        let res = self.provider.send_raw_transaction(&tx).await?;
336
337        Ok(res)
338    }
339
340    /// # Example
341    ///
342    /// ```
343    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
344    /// use cast::Cast;
345    ///
346    /// # async fn foo() -> eyre::Result<()> {
347    /// let provider =
348    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
349    /// let cast = Cast::new(provider);
350    /// let block = cast.block(5, true, None).await?;
351    /// println!("{}", block);
352    /// # Ok(())
353    /// # }
354    /// ```
355    pub async fn block<B: Into<BlockId>>(
356        &self,
357        block: B,
358        full: bool,
359        field: Option<String>,
360    ) -> Result<String> {
361        let block = block.into();
362        if let Some(ref field) = field {
363            if field == "transactions" && !full {
364                eyre::bail!("use --full to view transactions")
365            }
366        }
367
368        let block = self
369            .provider
370            .get_block(block)
371            .kind(full.into())
372            .await?
373            .ok_or_else(|| eyre::eyre!("block {:?} not found", block))?;
374
375        let block = if let Some(ref field) = field {
376            get_pretty_block_attr(&block, field)
377                .unwrap_or_else(|| format!("{field} is not a valid block field"))
378        } else if shell::is_json() {
379            serde_json::to_value(&block).unwrap().to_string()
380        } else {
381            block.pretty()
382        };
383
384        Ok(block)
385    }
386
387    async fn block_field_as_num<B: Into<BlockId>>(&self, block: B, field: String) -> Result<U256> {
388        Self::block(
389            self,
390            block.into(),
391            false,
392            // Select only select field
393            Some(field),
394        )
395        .await?
396        .parse()
397        .map_err(Into::into)
398    }
399
400    pub async fn base_fee<B: Into<BlockId>>(&self, block: B) -> Result<U256> {
401        Self::block_field_as_num(self, block, String::from("baseFeePerGas")).await
402    }
403
404    pub async fn age<B: Into<BlockId>>(&self, block: B) -> Result<String> {
405        let timestamp_str =
406            Self::block_field_as_num(self, block, String::from("timestamp")).await?.to_string();
407        let datetime = DateTime::from_timestamp(timestamp_str.parse::<i64>().unwrap(), 0).unwrap();
408        Ok(datetime.format("%a %b %e %H:%M:%S %Y").to_string())
409    }
410
411    pub async fn timestamp<B: Into<BlockId>>(&self, block: B) -> Result<U256> {
412        Self::block_field_as_num(self, block, "timestamp".to_string()).await
413    }
414
415    pub async fn chain(&self) -> Result<&str> {
416        let genesis_hash = Self::block(
417            self,
418            0,
419            false,
420            // Select only block hash
421            Some(String::from("hash")),
422        )
423        .await?;
424
425        Ok(match &genesis_hash[..] {
426            "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" => {
427                match &(Self::block(self, 1920000, false, Some("hash".to_string())).await?)[..] {
428                    "0x94365e3a8c0b35089c1d1195081fe7489b528a84b22199c916180db8b28ade7f" => {
429                        "etclive"
430                    }
431                    _ => "ethlive",
432                }
433            }
434            "0xa3c565fc15c7478862d50ccd6561e3c06b24cc509bf388941c25ea985ce32cb9" => "kovan",
435            "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d" => "ropsten",
436            "0x7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b" => {
437                "optimism-mainnet"
438            }
439            "0xc1fc15cd51159b1f1e5cbc4b82e85c1447ddfa33c52cf1d98d14fba0d6354be1" => {
440                "optimism-goerli"
441            }
442            "0x02adc9b449ff5f2467b8c674ece7ff9b21319d76c4ad62a67a70d552655927e5" => {
443                "optimism-kovan"
444            }
445            "0x521982bd54239dc71269eefb58601762cc15cfb2978e0becb46af7962ed6bfaa" => "fraxtal",
446            "0x910f5c4084b63fd860d0c2f9a04615115a5a991254700b39ba072290dbd77489" => {
447                "fraxtal-testnet"
448            }
449            "0x7ee576b35482195fc49205cec9af72ce14f003b9ae69f6ba0faef4514be8b442" => {
450                "arbitrum-mainnet"
451            }
452            "0x0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303" => "morden",
453            "0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177" => "rinkeby",
454            "0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a" => "goerli",
455            "0x14c2283285a88fe5fce9bf5c573ab03d6616695d717b12a127188bcacfc743c4" => "kotti",
456            "0xa9c28ce2141b56c474f1dc504bee9b01eb1bd7d1a507580d5519d4437a97de1b" => "polygon-pos",
457            "0x7202b2b53c5a0836e773e319d18922cc756dd67432f9a1f65352b61f4406c697" => {
458                "polygon-pos-amoy-testnet"
459            }
460            "0x81005434635456a16f74ff7023fbe0bf423abbc8a8deb093ffff455c0ad3b741" => "polygon-zkevm",
461            "0x676c1a76a6c5855a32bdf7c61977a0d1510088a4eeac1330466453b3d08b60b9" => {
462                "polygon-zkevm-cardona-testnet"
463            }
464            "0x4f1dd23188aab3a76b463e4af801b52b1248ef073c648cbdc4c9333d3da79756" => "gnosis",
465            "0xada44fd8d2ecab8b08f256af07ad3e777f17fb434f8f8e678b312f576212ba9a" => "chiado",
466            "0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34" => "bsctest",
467            "0x0d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5b" => "bsc",
468            "0x31ced5b9beb7f8782b014660da0cb18cc409f121f408186886e1ca3e8eeca96b" => {
469                match &(Self::block(self, 1, false, Some(String::from("hash"))).await?)[..] {
470                    "0x738639479dc82d199365626f90caa82f7eafcfe9ed354b456fb3d294597ceb53" => {
471                        "avalanche-fuji"
472                    }
473                    _ => "avalanche",
474                }
475            }
476            "0x23a2658170ba70d014ba0d0d2709f8fbfe2fa660cd868c5f282f991eecbe38ee" => "ink",
477            "0xe5fd5cf0be56af58ad5751b401410d6b7a09d830fa459789746a3d0dd1c79834" => "ink-sepolia",
478            _ => "unknown",
479        })
480    }
481
482    pub async fn chain_id(&self) -> Result<u64> {
483        Ok(self.provider.get_chain_id().await?)
484    }
485
486    pub async fn block_number(&self) -> Result<u64> {
487        Ok(self.provider.get_block_number().await?)
488    }
489
490    pub async fn gas_price(&self) -> Result<u128> {
491        Ok(self.provider.get_gas_price().await?)
492    }
493
494    /// # Example
495    ///
496    /// ```
497    /// use alloy_primitives::Address;
498    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
499    /// use cast::Cast;
500    /// use std::str::FromStr;
501    ///
502    /// # async fn foo() -> eyre::Result<()> {
503    /// let provider =
504    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
505    /// let cast = Cast::new(provider);
506    /// let addr = Address::from_str("0x7eD52863829AB99354F3a0503A622e82AcD5F7d3")?;
507    /// let nonce = cast.nonce(addr, None).await?;
508    /// println!("{}", nonce);
509    /// # Ok(())
510    /// # }
511    /// ```
512    pub async fn nonce(&self, who: Address, block: Option<BlockId>) -> Result<u64> {
513        Ok(self.provider.get_transaction_count(who).block_id(block.unwrap_or_default()).await?)
514    }
515
516    /// #Example
517    ///
518    /// ```
519    /// use alloy_primitives::{Address, FixedBytes};
520    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
521    /// use cast::Cast;
522    /// use std::str::FromStr;
523    ///
524    /// # async fn foo() -> eyre::Result<()> {
525    /// let provider =
526    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
527    /// let cast = Cast::new(provider);
528    /// let addr = Address::from_str("0x7eD52863829AB99354F3a0503A622e82AcD5F7d3")?;
529    /// let slots = vec![FixedBytes::from_str("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")?];
530    /// let codehash = cast.codehash(addr, slots, None).await?;
531    /// println!("{}", codehash);
532    /// # Ok(())
533    /// # }
534    pub async fn codehash(
535        &self,
536        who: Address,
537        slots: Vec<B256>,
538        block: Option<BlockId>,
539    ) -> Result<String> {
540        Ok(self
541            .provider
542            .get_proof(who, slots)
543            .block_id(block.unwrap_or_default())
544            .await?
545            .code_hash
546            .to_string())
547    }
548
549    /// #Example
550    ///
551    /// ```
552    /// use alloy_primitives::{Address, FixedBytes};
553    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
554    /// use cast::Cast;
555    /// use std::str::FromStr;
556    ///
557    /// # async fn foo() -> eyre::Result<()> {
558    /// let provider =
559    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
560    /// let cast = Cast::new(provider);
561    /// let addr = Address::from_str("0x7eD52863829AB99354F3a0503A622e82AcD5F7d3")?;
562    /// let slots = vec![FixedBytes::from_str("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")?];
563    /// let storage_root = cast.storage_root(addr, slots, None).await?;
564    /// println!("{}", storage_root);
565    /// # Ok(())
566    /// # }
567    pub async fn storage_root(
568        &self,
569        who: Address,
570        slots: Vec<B256>,
571        block: Option<BlockId>,
572    ) -> Result<String> {
573        Ok(self
574            .provider
575            .get_proof(who, slots)
576            .block_id(block.unwrap_or_default())
577            .await?
578            .storage_hash
579            .to_string())
580    }
581
582    /// # Example
583    ///
584    /// ```
585    /// use alloy_primitives::Address;
586    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
587    /// use cast::Cast;
588    /// use std::str::FromStr;
589    ///
590    /// # async fn foo() -> eyre::Result<()> {
591    /// let provider =
592    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
593    /// let cast = Cast::new(provider);
594    /// let addr = Address::from_str("0x7eD52863829AB99354F3a0503A622e82AcD5F7d3")?;
595    /// let implementation = cast.implementation(addr, false, None).await?;
596    /// println!("{}", implementation);
597    /// # Ok(())
598    /// # }
599    /// ```
600    pub async fn implementation(
601        &self,
602        who: Address,
603        is_beacon: bool,
604        block: Option<BlockId>,
605    ) -> Result<String> {
606        let slot = match is_beacon {
607            true => {
608                // Use the beacon slot : bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)
609                B256::from_str(
610                    "0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50",
611                )?
612            }
613            false => {
614                // Use the implementation slot :
615                // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
616                B256::from_str(
617                    "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
618                )?
619            }
620        };
621
622        let value = self
623            .provider
624            .get_storage_at(who, slot.into())
625            .block_id(block.unwrap_or_default())
626            .await?;
627        let addr = Address::from_word(value.into());
628        Ok(format!("{addr:?}"))
629    }
630
631    /// # Example
632    ///
633    /// ```
634    /// use alloy_primitives::Address;
635    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
636    /// use cast::Cast;
637    /// use std::str::FromStr;
638    ///
639    /// # async fn foo() -> eyre::Result<()> {
640    /// let provider =
641    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
642    /// let cast = Cast::new(provider);
643    /// let addr = Address::from_str("0x7eD52863829AB99354F3a0503A622e82AcD5F7d3")?;
644    /// let admin = cast.admin(addr, None).await?;
645    /// println!("{}", admin);
646    /// # Ok(())
647    /// # }
648    /// ```
649    pub async fn admin(&self, who: Address, block: Option<BlockId>) -> Result<String> {
650        let slot =
651            B256::from_str("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103")?;
652        let value = self
653            .provider
654            .get_storage_at(who, slot.into())
655            .block_id(block.unwrap_or_default())
656            .await?;
657        let addr = Address::from_word(value.into());
658        Ok(format!("{addr:?}"))
659    }
660
661    /// # Example
662    ///
663    /// ```
664    /// use alloy_primitives::{Address, U256};
665    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
666    /// use cast::Cast;
667    /// use std::str::FromStr;
668    ///
669    /// # async fn foo() -> eyre::Result<()> {
670    /// let provider =
671    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
672    /// let cast = Cast::new(provider);
673    /// let addr = Address::from_str("7eD52863829AB99354F3a0503A622e82AcD5F7d3")?;
674    /// let computed_address = cast.compute_address(addr, None).await?;
675    /// println!("Computed address for address {addr}: {computed_address}");
676    /// # Ok(())
677    /// # }
678    /// ```
679    pub async fn compute_address(&self, address: Address, nonce: Option<u64>) -> Result<Address> {
680        let unpacked = if let Some(n) = nonce { n } else { self.nonce(address, None).await? };
681        Ok(address.create(unpacked))
682    }
683
684    /// # Example
685    ///
686    /// ```
687    /// use alloy_primitives::Address;
688    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
689    /// use cast::Cast;
690    /// use std::str::FromStr;
691    ///
692    /// # async fn foo() -> eyre::Result<()> {
693    /// let provider =
694    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
695    /// let cast = Cast::new(provider);
696    /// let addr = Address::from_str("0x00000000219ab540356cbb839cbe05303d7705fa")?;
697    /// let code = cast.code(addr, None, false).await?;
698    /// println!("{}", code);
699    /// # Ok(())
700    /// # }
701    /// ```
702    pub async fn code(
703        &self,
704        who: Address,
705        block: Option<BlockId>,
706        disassemble: bool,
707    ) -> Result<String> {
708        if disassemble {
709            let code =
710                self.provider.get_code_at(who).block_id(block.unwrap_or_default()).await?.to_vec();
711            SimpleCast::disassemble(&code)
712        } else {
713            Ok(format!(
714                "{}",
715                self.provider.get_code_at(who).block_id(block.unwrap_or_default()).await?
716            ))
717        }
718    }
719
720    /// Example
721    ///
722    /// ```
723    /// use alloy_primitives::Address;
724    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
725    /// use cast::Cast;
726    /// use std::str::FromStr;
727    ///
728    /// # async fn foo() -> eyre::Result<()> {
729    /// let provider =
730    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
731    /// let cast = Cast::new(provider);
732    /// let addr = Address::from_str("0x00000000219ab540356cbb839cbe05303d7705fa")?;
733    /// let codesize = cast.codesize(addr, None).await?;
734    /// println!("{}", codesize);
735    /// # Ok(())
736    /// # }
737    /// ```
738    pub async fn codesize(&self, who: Address, block: Option<BlockId>) -> Result<String> {
739        let code =
740            self.provider.get_code_at(who).block_id(block.unwrap_or_default()).await?.to_vec();
741        Ok(format!("{}", code.len()))
742    }
743
744    /// # Example
745    ///
746    /// ```
747    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
748    /// use cast::Cast;
749    ///
750    /// # async fn foo() -> eyre::Result<()> {
751    /// let provider =
752    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
753    /// let cast = Cast::new(provider);
754    /// let tx_hash = "0xf8d1713ea15a81482958fb7ddf884baee8d3bcc478c5f2f604e008dc788ee4fc";
755    /// let tx = cast.transaction(Some(tx_hash.to_string()), None, None, None, false).await?;
756    /// println!("{}", tx);
757    /// # Ok(())
758    /// # }
759    /// ```
760    pub async fn transaction(
761        &self,
762        tx_hash: Option<String>,
763        from: Option<NameOrAddress>,
764        nonce: Option<u64>,
765        field: Option<String>,
766        raw: bool,
767    ) -> Result<String> {
768        let tx = if let Some(tx_hash) = tx_hash {
769            let tx_hash = TxHash::from_str(&tx_hash).wrap_err("invalid tx hash")?;
770            self.provider
771                .get_transaction_by_hash(tx_hash)
772                .await?
773                .ok_or_else(|| eyre::eyre!("tx not found: {:?}", tx_hash))?
774        } else if let Some(from) = from {
775            // If nonce is not provided, uses 0.
776            let nonce = U64::from(nonce.unwrap_or_default());
777            let from = from.resolve(self.provider.root()).await?;
778
779            self.provider
780                .raw_request::<_, Option<AnyRpcTransaction>>(
781                    "eth_getTransactionBySenderAndNonce".into(),
782                    (from, nonce),
783                )
784                .await?
785                .ok_or_else(|| {
786                    eyre::eyre!("tx not found for sender {from} and nonce {:?}", nonce.to::<u64>())
787                })?
788        } else {
789            eyre::bail!("tx hash or from address is required")
790        };
791
792        Ok(if raw {
793            // also consider opstack deposit transactions
794            let either_tx = tx.try_into_either::<OpTxEnvelope>()?;
795            let encoded = either_tx.encoded_2718();
796            format!("0x{}", hex::encode(encoded))
797        } else if let Some(field) = field {
798            get_pretty_tx_attr(&tx.inner, field.as_str())
799                .ok_or_else(|| eyre::eyre!("invalid tx field: {}", field.to_string()))?
800        } else if shell::is_json() {
801            // to_value first to sort json object keys
802            serde_json::to_value(&tx)?.to_string()
803        } else {
804            tx.pretty()
805        })
806    }
807
808    /// # Example
809    ///
810    /// ```
811    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
812    /// use cast::Cast;
813    ///
814    /// # async fn foo() -> eyre::Result<()> {
815    /// let provider =
816    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
817    /// let cast = Cast::new(provider);
818    /// let tx_hash = "0xf8d1713ea15a81482958fb7ddf884baee8d3bcc478c5f2f604e008dc788ee4fc";
819    /// let receipt = cast.receipt(tx_hash.to_string(), None, 1, None, false).await?;
820    /// println!("{}", receipt);
821    /// # Ok(())
822    /// # }
823    /// ```
824    pub async fn receipt(
825        &self,
826        tx_hash: String,
827        field: Option<String>,
828        confs: u64,
829        timeout: Option<u64>,
830        cast_async: bool,
831    ) -> Result<String> {
832        let tx_hash = TxHash::from_str(&tx_hash).wrap_err("invalid tx hash")?;
833
834        let mut receipt: TransactionReceiptWithRevertReason =
835            match self.provider.get_transaction_receipt(tx_hash).await? {
836                Some(r) => r,
837                None => {
838                    // if the async flag is provided, immediately exit if no tx is found, otherwise
839                    // try to poll for it
840                    if cast_async {
841                        eyre::bail!("tx not found: {:?}", tx_hash)
842                    } else {
843                        PendingTransactionBuilder::new(self.provider.root().clone(), tx_hash)
844                            .with_required_confirmations(confs)
845                            .with_timeout(timeout.map(Duration::from_secs))
846                            .get_receipt()
847                            .await?
848                    }
849                }
850            }
851            .into();
852
853        // Allow to fail silently
854        let _ = receipt.update_revert_reason(&self.provider).await;
855
856        Ok(if let Some(ref field) = field {
857            get_pretty_tx_receipt_attr(&receipt, field)
858                .ok_or_else(|| eyre::eyre!("invalid receipt field: {}", field))?
859        } else if shell::is_json() {
860            // to_value first to sort json object keys
861            serde_json::to_value(&receipt)?.to_string()
862        } else {
863            receipt.pretty()
864        })
865    }
866
867    /// Perform a raw JSON-RPC request
868    ///
869    /// # Example
870    ///
871    /// ```
872    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
873    /// use cast::Cast;
874    ///
875    /// # async fn foo() -> eyre::Result<()> {
876    /// let provider =
877    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
878    /// let cast = Cast::new(provider);
879    /// let result = cast
880    ///     .rpc("eth_getBalance", &["0xc94770007dda54cF92009BFF0dE90c06F603a09f", "latest"])
881    ///     .await?;
882    /// println!("{}", result);
883    /// # Ok(())
884    /// # }
885    /// ```
886    pub async fn rpc<V>(&self, method: &str, params: V) -> Result<String>
887    where
888        V: alloy_json_rpc::RpcSend,
889    {
890        let res = self
891            .provider
892            .raw_request::<V, serde_json::Value>(Cow::Owned(method.to_string()), params)
893            .await?;
894        Ok(serde_json::to_string(&res)?)
895    }
896
897    /// Returns the slot
898    ///
899    /// # Example
900    ///
901    /// ```
902    /// use alloy_primitives::{Address, B256};
903    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
904    /// use cast::Cast;
905    /// use std::str::FromStr;
906    ///
907    /// # async fn foo() -> eyre::Result<()> {
908    /// let provider =
909    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
910    /// let cast = Cast::new(provider);
911    /// let addr = Address::from_str("0x00000000006c3852cbEf3e08E8dF289169EdE581")?;
912    /// let slot = B256::ZERO;
913    /// let storage = cast.storage(addr, slot, None).await?;
914    /// println!("{}", storage);
915    /// # Ok(())
916    /// # }
917    /// ```
918    pub async fn storage(
919        &self,
920        from: Address,
921        slot: B256,
922        block: Option<BlockId>,
923    ) -> Result<String> {
924        Ok(format!(
925            "{:?}",
926            B256::from(
927                self.provider
928                    .get_storage_at(from, slot.into())
929                    .block_id(block.unwrap_or_default())
930                    .await?
931            )
932        ))
933    }
934
935    pub async fn filter_logs(&self, filter: Filter) -> Result<String> {
936        let logs = self.provider.get_logs(&filter).await?;
937
938        let res = if shell::is_json() {
939            serde_json::to_string(&logs)?
940        } else {
941            let mut s = vec![];
942            for log in logs {
943                let pretty = log
944                    .pretty()
945                    .replacen('\n', "- ", 1) // Remove empty first line
946                    .replace('\n', "\n  "); // Indent
947                s.push(pretty);
948            }
949            s.join("\n")
950        };
951        Ok(res)
952    }
953
954    /// Converts a block identifier into a block number.
955    ///
956    /// If the block identifier is a block number, then this function returns the block number. If
957    /// the block identifier is a block hash, then this function returns the block number of
958    /// that block hash. If the block identifier is `None`, then this function returns `None`.
959    ///
960    /// # Example
961    ///
962    /// ```
963    /// use alloy_primitives::fixed_bytes;
964    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
965    /// use alloy_rpc_types::{BlockId, BlockNumberOrTag};
966    /// use cast::Cast;
967    /// use std::{convert::TryFrom, str::FromStr};
968    ///
969    /// # async fn foo() -> eyre::Result<()> {
970    /// let provider =
971    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("http://localhost:8545").await?;
972    /// let cast = Cast::new(provider);
973    ///
974    /// let block_number = cast.convert_block_number(Some(BlockId::number(5))).await?;
975    /// assert_eq!(block_number, Some(BlockNumberOrTag::Number(5)));
976    ///
977    /// let block_number = cast
978    ///     .convert_block_number(Some(BlockId::hash(fixed_bytes!(
979    ///         "0000000000000000000000000000000000000000000000000000000000001234"
980    ///     ))))
981    ///     .await?;
982    /// assert_eq!(block_number, Some(BlockNumberOrTag::Number(4660)));
983    ///
984    /// let block_number = cast.convert_block_number(None).await?;
985    /// assert_eq!(block_number, None);
986    /// # Ok(())
987    /// # }
988    /// ```
989    pub async fn convert_block_number(
990        &self,
991        block: Option<BlockId>,
992    ) -> Result<Option<BlockNumberOrTag>, eyre::Error> {
993        match block {
994            Some(block) => match block {
995                BlockId::Number(block_number) => Ok(Some(block_number)),
996                BlockId::Hash(hash) => {
997                    let block = self.provider.get_block_by_hash(hash.block_hash).await?;
998                    Ok(block.map(|block| block.header.number).map(BlockNumberOrTag::from))
999                }
1000            },
1001            None => Ok(None),
1002        }
1003    }
1004
1005    /// Sets up a subscription to the given filter and writes the logs to the given output.
1006    ///
1007    /// # Example
1008    ///
1009    /// ```
1010    /// use alloy_primitives::Address;
1011    /// use alloy_provider::{network::AnyNetwork, ProviderBuilder, RootProvider};
1012    /// use alloy_rpc_types::Filter;
1013    /// use alloy_transport::BoxTransport;
1014    /// use cast::Cast;
1015    /// use std::{io, str::FromStr};
1016    ///
1017    /// # async fn foo() -> eyre::Result<()> {
1018    /// let provider =
1019    ///     ProviderBuilder::<_, _, AnyNetwork>::default().connect("wss://localhost:8545").await?;
1020    /// let cast = Cast::new(provider);
1021    ///
1022    /// let filter =
1023    ///     Filter::new().address(Address::from_str("0x00000000006c3852cbEf3e08E8dF289169EdE581")?);
1024    /// let mut output = io::stdout();
1025    /// cast.subscribe(filter, &mut output).await?;
1026    /// # Ok(())
1027    /// # }
1028    /// ```
1029    pub async fn subscribe(&self, filter: Filter, output: &mut dyn io::Write) -> Result<()> {
1030        // Initialize the subscription stream for logs
1031        let mut subscription = self.provider.subscribe_logs(&filter).await?.into_stream();
1032
1033        // Check if a to_block is specified, if so, subscribe to blocks
1034        let mut block_subscription = if filter.get_to_block().is_some() {
1035            Some(self.provider.subscribe_blocks().await?.into_stream())
1036        } else {
1037            None
1038        };
1039
1040        let format_json = shell::is_json();
1041        let to_block_number = filter.get_to_block();
1042
1043        // If output should be JSON, start with an opening bracket
1044        if format_json {
1045            write!(output, "[")?;
1046        }
1047
1048        let mut first = true;
1049
1050        loop {
1051            tokio::select! {
1052                // If block subscription is present, listen to it to avoid blocking indefinitely past the desired to_block
1053                block = if let Some(bs) = &mut block_subscription {
1054                    Either::Left(bs.next().fuse())
1055                } else {
1056                    Either::Right(futures::future::pending())
1057                } => {
1058                    if let (Some(block), Some(to_block)) = (block, to_block_number) {
1059                        if block.number  > to_block {
1060                            break;
1061                        }
1062                    }
1063                },
1064                // Process incoming log
1065                log = subscription.next() => {
1066                    if format_json {
1067                        if !first {
1068                            write!(output, ",")?;
1069                        }
1070                        first = false;
1071                        let log_str = serde_json::to_string(&log).unwrap();
1072                        write!(output, "{log_str}")?;
1073                    } else {
1074                        let log_str = log.pretty()
1075                            .replacen('\n', "- ", 1)  // Remove empty first line
1076                            .replace('\n', "\n  ");  // Indent
1077                        writeln!(output, "{log_str}")?;
1078                    }
1079                },
1080                // Break on cancel signal, to allow for closing JSON bracket
1081                _ = ctrl_c() => {
1082                    break;
1083                },
1084                else => break,
1085            }
1086        }
1087
1088        // If output was JSON, end with a closing bracket
1089        if format_json {
1090            write!(output, "]")?;
1091        }
1092
1093        Ok(())
1094    }
1095
1096    pub async fn erc20_balance(
1097        &self,
1098        token: Address,
1099        owner: Address,
1100        block: Option<BlockId>,
1101    ) -> Result<U256> {
1102        Ok(IERC20::new(token, &self.provider)
1103            .balanceOf(owner)
1104            .block(block.unwrap_or_default())
1105            .call()
1106            .await?)
1107    }
1108}
1109
1110pub struct SimpleCast;
1111
1112impl SimpleCast {
1113    /// Returns the maximum value of the given integer type
1114    ///
1115    /// # Example
1116    ///
1117    /// ```
1118    /// use alloy_primitives::{I256, U256};
1119    /// use cast::SimpleCast;
1120    ///
1121    /// assert_eq!(SimpleCast::max_int("uint256")?, U256::MAX.to_string());
1122    /// assert_eq!(SimpleCast::max_int("int256")?, I256::MAX.to_string());
1123    /// assert_eq!(SimpleCast::max_int("int32")?, i32::MAX.to_string());
1124    /// # Ok::<(), eyre::Report>(())
1125    /// ```
1126    pub fn max_int(s: &str) -> Result<String> {
1127        Self::max_min_int::<true>(s)
1128    }
1129
1130    /// Returns the maximum value of the given integer type
1131    ///
1132    /// # Example
1133    ///
1134    /// ```
1135    /// use alloy_primitives::{I256, U256};
1136    /// use cast::SimpleCast;
1137    ///
1138    /// assert_eq!(SimpleCast::min_int("uint256")?, "0");
1139    /// assert_eq!(SimpleCast::min_int("int256")?, I256::MIN.to_string());
1140    /// assert_eq!(SimpleCast::min_int("int32")?, i32::MIN.to_string());
1141    /// # Ok::<(), eyre::Report>(())
1142    /// ```
1143    pub fn min_int(s: &str) -> Result<String> {
1144        Self::max_min_int::<false>(s)
1145    }
1146
1147    fn max_min_int<const MAX: bool>(s: &str) -> Result<String> {
1148        let ty = DynSolType::parse(s).wrap_err("Invalid type, expected `(u)int<bit size>`")?;
1149        match ty {
1150            DynSolType::Int(n) => {
1151                let mask = U256::from(1).wrapping_shl(n - 1);
1152                let max = (U256::MAX & mask).saturating_sub(U256::from(1));
1153                if MAX {
1154                    Ok(max.to_string())
1155                } else {
1156                    let min = I256::from_raw(max).wrapping_neg() + I256::MINUS_ONE;
1157                    Ok(min.to_string())
1158                }
1159            }
1160            DynSolType::Uint(n) => {
1161                if MAX {
1162                    let mut max = U256::MAX;
1163                    if n < 255 {
1164                        max &= U256::from(1).wrapping_shl(n).wrapping_sub(U256::from(1));
1165                    }
1166                    Ok(max.to_string())
1167                } else {
1168                    Ok("0".to_string())
1169                }
1170            }
1171            _ => Err(eyre::eyre!("Type is not int/uint: {s}")),
1172        }
1173    }
1174
1175    /// Converts UTF-8 text input to hex
1176    ///
1177    /// # Example
1178    ///
1179    /// ```
1180    /// use cast::SimpleCast as Cast;
1181    ///
1182    /// assert_eq!(Cast::from_utf8("yo"), "0x796f");
1183    /// assert_eq!(Cast::from_utf8("Hello, World!"), "0x48656c6c6f2c20576f726c6421");
1184    /// assert_eq!(Cast::from_utf8("TurboDappTools"), "0x547572626f44617070546f6f6c73");
1185    /// # Ok::<_, eyre::Report>(())
1186    /// ```
1187    pub fn from_utf8(s: &str) -> String {
1188        hex::encode_prefixed(s)
1189    }
1190
1191    /// Converts hex input to UTF-8 text
1192    ///
1193    /// # Example
1194    ///
1195    /// ```
1196    /// use cast::SimpleCast as Cast;
1197    ///
1198    /// assert_eq!(Cast::to_utf8("0x796f")?, "yo");
1199    /// assert_eq!(Cast::to_utf8("0x48656c6c6f2c20576f726c6421")?, "Hello, World!");
1200    /// assert_eq!(Cast::to_utf8("0x547572626f44617070546f6f6c73")?, "TurboDappTools");
1201    /// assert_eq!(Cast::to_utf8("0xe4bda0e5a5bd")?, "你好");
1202    /// # Ok::<_, eyre::Report>(())
1203    /// ```
1204    pub fn to_utf8(s: &str) -> Result<String> {
1205        let bytes = hex::decode(s)?;
1206        Ok(String::from_utf8_lossy(bytes.as_ref()).to_string())
1207    }
1208
1209    /// Converts hex data into text data
1210    ///
1211    /// # Example
1212    ///
1213    /// ```
1214    /// use cast::SimpleCast as Cast;
1215    ///
1216    /// assert_eq!(Cast::to_ascii("0x796f")?, "yo");
1217    /// assert_eq!(Cast::to_ascii("48656c6c6f2c20576f726c6421")?, "Hello, World!");
1218    /// assert_eq!(Cast::to_ascii("0x547572626f44617070546f6f6c73")?, "TurboDappTools");
1219    /// # Ok::<_, eyre::Report>(())
1220    /// ```
1221    pub fn to_ascii(hex: &str) -> Result<String> {
1222        let bytes = hex::decode(hex)?;
1223        if !bytes.iter().all(u8::is_ascii) {
1224            return Err(eyre::eyre!("Invalid ASCII bytes"));
1225        }
1226        Ok(String::from_utf8(bytes).unwrap())
1227    }
1228
1229    /// Converts fixed point number into specified number of decimals
1230    /// ```
1231    /// use alloy_primitives::U256;
1232    /// use cast::SimpleCast as Cast;
1233    ///
1234    /// assert_eq!(Cast::from_fixed_point("10", "0")?, "10");
1235    /// assert_eq!(Cast::from_fixed_point("1.0", "1")?, "10");
1236    /// assert_eq!(Cast::from_fixed_point("0.10", "2")?, "10");
1237    /// assert_eq!(Cast::from_fixed_point("0.010", "3")?, "10");
1238    /// # Ok::<_, eyre::Report>(())
1239    /// ```
1240    pub fn from_fixed_point(value: &str, decimals: &str) -> Result<String> {
1241        // TODO: https://github.com/alloy-rs/core/pull/461
1242        let units: Unit = if let Ok(x) = decimals.parse() {
1243            Unit::new(x).ok_or_else(|| eyre::eyre!("invalid unit"))?
1244        } else {
1245            decimals.parse()?
1246        };
1247        let n = ParseUnits::parse_units(value, units)?;
1248        Ok(n.to_string())
1249    }
1250
1251    /// Converts integers with specified decimals into fixed point numbers
1252    ///
1253    /// # Example
1254    ///
1255    /// ```
1256    /// use alloy_primitives::U256;
1257    /// use cast::SimpleCast as Cast;
1258    ///
1259    /// assert_eq!(Cast::to_fixed_point("10", "0")?, "10.");
1260    /// assert_eq!(Cast::to_fixed_point("10", "1")?, "1.0");
1261    /// assert_eq!(Cast::to_fixed_point("10", "2")?, "0.10");
1262    /// assert_eq!(Cast::to_fixed_point("10", "3")?, "0.010");
1263    ///
1264    /// assert_eq!(Cast::to_fixed_point("-10", "0")?, "-10.");
1265    /// assert_eq!(Cast::to_fixed_point("-10", "1")?, "-1.0");
1266    /// assert_eq!(Cast::to_fixed_point("-10", "2")?, "-0.10");
1267    /// assert_eq!(Cast::to_fixed_point("-10", "3")?, "-0.010");
1268    /// # Ok::<_, eyre::Report>(())
1269    /// ```
1270    pub fn to_fixed_point(value: &str, decimals: &str) -> Result<String> {
1271        let (sign, mut value, value_len) = {
1272            let number = NumberWithBase::parse_int(value, None)?;
1273            let sign = if number.is_nonnegative() { "" } else { "-" };
1274            let value = format!("{number:#}");
1275            let value_stripped = value.strip_prefix('-').unwrap_or(&value).to_string();
1276            let value_len = value_stripped.len();
1277            (sign, value_stripped, value_len)
1278        };
1279        let decimals = NumberWithBase::parse_uint(decimals, None)?.number().to::<usize>();
1280
1281        let value = if decimals >= value_len {
1282            // Add "0." and pad with 0s
1283            format!("0.{value:0>decimals$}")
1284        } else {
1285            // Insert decimal at -idx (i.e 1 => decimal idx = -1)
1286            value.insert(value_len - decimals, '.');
1287            value
1288        };
1289
1290        Ok(format!("{sign}{value}"))
1291    }
1292
1293    /// Concatencates hex strings
1294    ///
1295    /// # Example
1296    ///
1297    /// ```
1298    /// use cast::SimpleCast as Cast;
1299    ///
1300    /// assert_eq!(Cast::concat_hex(["0x00", "0x01"]), "0x0001");
1301    /// assert_eq!(Cast::concat_hex(["1", "2"]), "0x12");
1302    /// # Ok::<_, eyre::Report>(())
1303    /// ```
1304    pub fn concat_hex<T: AsRef<str>>(values: impl IntoIterator<Item = T>) -> String {
1305        let mut out = String::new();
1306        for s in values {
1307            let s = s.as_ref();
1308            out.push_str(s.strip_prefix("0x").unwrap_or(s))
1309        }
1310        format!("0x{out}")
1311    }
1312
1313    /// Converts a number into uint256 hex string with 0x prefix
1314    ///
1315    /// # Example
1316    ///
1317    /// ```
1318    /// use cast::SimpleCast as Cast;
1319    ///
1320    /// assert_eq!(
1321    ///     Cast::to_uint256("100")?,
1322    ///     "0x0000000000000000000000000000000000000000000000000000000000000064"
1323    /// );
1324    /// assert_eq!(
1325    ///     Cast::to_uint256("192038293923")?,
1326    ///     "0x0000000000000000000000000000000000000000000000000000002cb65fd1a3"
1327    /// );
1328    /// assert_eq!(
1329    ///     Cast::to_uint256(
1330    ///         "115792089237316195423570985008687907853269984665640564039457584007913129639935"
1331    ///     )?,
1332    ///     "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1333    /// );
1334    /// # Ok::<_, eyre::Report>(())
1335    /// ```
1336    pub fn to_uint256(value: &str) -> Result<String> {
1337        let n = NumberWithBase::parse_uint(value, None)?;
1338        Ok(format!("{n:#066x}"))
1339    }
1340
1341    /// Converts a number into int256 hex string with 0x prefix
1342    ///
1343    /// # Example
1344    ///
1345    /// ```
1346    /// use cast::SimpleCast as Cast;
1347    ///
1348    /// assert_eq!(
1349    ///     Cast::to_int256("0")?,
1350    ///     "0x0000000000000000000000000000000000000000000000000000000000000000"
1351    /// );
1352    /// assert_eq!(
1353    ///     Cast::to_int256("100")?,
1354    ///     "0x0000000000000000000000000000000000000000000000000000000000000064"
1355    /// );
1356    /// assert_eq!(
1357    ///     Cast::to_int256("-100")?,
1358    ///     "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c"
1359    /// );
1360    /// assert_eq!(
1361    ///     Cast::to_int256("192038293923")?,
1362    ///     "0x0000000000000000000000000000000000000000000000000000002cb65fd1a3"
1363    /// );
1364    /// assert_eq!(
1365    ///     Cast::to_int256("-192038293923")?,
1366    ///     "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffd349a02e5d"
1367    /// );
1368    /// assert_eq!(
1369    ///     Cast::to_int256(
1370    ///         "57896044618658097711785492504343953926634992332820282019728792003956564819967"
1371    ///     )?,
1372    ///     "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1373    /// );
1374    /// assert_eq!(
1375    ///     Cast::to_int256(
1376    ///         "-57896044618658097711785492504343953926634992332820282019728792003956564819968"
1377    ///     )?,
1378    ///     "0x8000000000000000000000000000000000000000000000000000000000000000"
1379    /// );
1380    /// # Ok::<_, eyre::Report>(())
1381    /// ```
1382    pub fn to_int256(value: &str) -> Result<String> {
1383        let n = NumberWithBase::parse_int(value, None)?;
1384        Ok(format!("{n:#066x}"))
1385    }
1386
1387    /// Converts an eth amount into a specified unit
1388    ///
1389    /// # Example
1390    ///
1391    /// ```
1392    /// use cast::SimpleCast as Cast;
1393    ///
1394    /// assert_eq!(Cast::to_unit("1 wei", "wei")?, "1");
1395    /// assert_eq!(Cast::to_unit("1", "wei")?, "1");
1396    /// assert_eq!(Cast::to_unit("1ether", "wei")?, "1000000000000000000");
1397    /// # Ok::<_, eyre::Report>(())
1398    /// ```
1399    pub fn to_unit(value: &str, unit: &str) -> Result<String> {
1400        let value = DynSolType::coerce_str(&DynSolType::Uint(256), value)?
1401            .as_uint()
1402            .wrap_err("Could not convert to uint")?
1403            .0;
1404        let unit = unit.parse().wrap_err("could not parse units")?;
1405        Ok(Self::format_unit_as_string(value, unit))
1406    }
1407
1408    /// Convert a number into a uint with arbitrary decimals.
1409    ///
1410    /// # Example
1411    ///
1412    /// ```
1413    /// use cast::SimpleCast as Cast;
1414    ///
1415    /// # fn main() -> eyre::Result<()> {
1416    /// assert_eq!(Cast::parse_units("1.0", 6)?, "1000000"); // USDC (6 decimals)
1417    /// assert_eq!(Cast::parse_units("2.5", 6)?, "2500000");
1418    /// assert_eq!(Cast::parse_units("1.0", 12)?, "1000000000000"); // 12 decimals
1419    /// assert_eq!(Cast::parse_units("1.23", 3)?, "1230"); // 3 decimals
1420    /// # Ok(())
1421    /// # }
1422    /// ```
1423    pub fn parse_units(value: &str, unit: u8) -> Result<String> {
1424        let unit = Unit::new(unit).ok_or_else(|| eyre::eyre!("invalid unit"))?;
1425
1426        Ok(ParseUnits::parse_units(value, unit)?.to_string())
1427    }
1428
1429    /// Format a number from smallest unit to decimal with arbitrary decimals.
1430    ///
1431    /// # Example
1432    ///
1433    /// ```
1434    /// use cast::SimpleCast as Cast;
1435    ///
1436    /// # fn main() -> eyre::Result<()> {
1437    /// assert_eq!(Cast::format_units("1000000", 6)?, "1"); // USDC (6 decimals)
1438    /// assert_eq!(Cast::format_units("2500000", 6)?, "2.500000");
1439    /// assert_eq!(Cast::format_units("1000000000000", 12)?, "1"); // 12 decimals
1440    /// assert_eq!(Cast::format_units("1230", 3)?, "1.230"); // 3 decimals
1441    /// # Ok(())
1442    /// # }
1443    /// ```
1444    pub fn format_units(value: &str, unit: u8) -> Result<String> {
1445        let value = NumberWithBase::parse_int(value, None)?.number();
1446        let unit = Unit::new(unit).ok_or_else(|| eyre::eyre!("invalid unit"))?;
1447        Ok(Self::format_unit_as_string(value, unit))
1448    }
1449
1450    // Helper function to format units as a string
1451    fn format_unit_as_string(value: U256, unit: Unit) -> String {
1452        let mut formatted = ParseUnits::U256(value).format_units(unit);
1453        // Trim empty fractional part.
1454        if let Some(dot) = formatted.find('.') {
1455            let fractional = &formatted[dot + 1..];
1456            if fractional.chars().all(|c: char| c == '0') {
1457                formatted = formatted[..dot].to_string();
1458            }
1459        }
1460        formatted
1461    }
1462
1463    /// Converts wei into an eth amount
1464    ///
1465    /// # Example
1466    ///
1467    /// ```
1468    /// use cast::SimpleCast as Cast;
1469    ///
1470    /// assert_eq!(Cast::from_wei("1", "gwei")?, "0.000000001");
1471    /// assert_eq!(Cast::from_wei("12340000005", "gwei")?, "12.340000005");
1472    /// assert_eq!(Cast::from_wei("10", "ether")?, "0.000000000000000010");
1473    /// assert_eq!(Cast::from_wei("100", "eth")?, "0.000000000000000100");
1474    /// assert_eq!(Cast::from_wei("17", "ether")?, "0.000000000000000017");
1475    /// # Ok::<_, eyre::Report>(())
1476    /// ```
1477    pub fn from_wei(value: &str, unit: &str) -> Result<String> {
1478        let value = NumberWithBase::parse_int(value, None)?.number();
1479        Ok(ParseUnits::U256(value).format_units(unit.parse()?))
1480    }
1481
1482    /// Converts an eth amount into wei
1483    ///
1484    /// # Example
1485    ///
1486    /// ```
1487    /// use cast::SimpleCast as Cast;
1488    ///
1489    /// assert_eq!(Cast::to_wei("100", "gwei")?, "100000000000");
1490    /// assert_eq!(Cast::to_wei("100", "eth")?, "100000000000000000000");
1491    /// assert_eq!(Cast::to_wei("1000", "ether")?, "1000000000000000000000");
1492    /// # Ok::<_, eyre::Report>(())
1493    /// ```
1494    pub fn to_wei(value: &str, unit: &str) -> Result<String> {
1495        let unit = unit.parse().wrap_err("could not parse units")?;
1496        Ok(ParseUnits::parse_units(value, unit)?.to_string())
1497    }
1498
1499    // Decodes RLP encoded data with validation for canonical integer representation
1500    ///
1501    /// # Examples
1502    /// ```
1503    /// use cast::SimpleCast as Cast;
1504    ///
1505    /// assert_eq!(Cast::from_rlp("0xc0", false).unwrap(), "[]");
1506    /// assert_eq!(Cast::from_rlp("0x0f", false).unwrap(), "\"0x0f\"");
1507    /// assert_eq!(Cast::from_rlp("0x33", false).unwrap(), "\"0x33\"");
1508    /// assert_eq!(Cast::from_rlp("0xc161", false).unwrap(), "[\"0x61\"]");
1509    /// assert_eq!(Cast::from_rlp("820002", true).is_err(), true);
1510    /// assert_eq!(Cast::from_rlp("820002", false).unwrap(), "\"0x0002\"");
1511    /// assert_eq!(Cast::from_rlp("00", true).is_err(), true);
1512    /// assert_eq!(Cast::from_rlp("00", false).unwrap(), "\"0x00\"");
1513    /// # Ok::<_, eyre::Report>(())
1514    /// ```
1515    pub fn from_rlp(value: impl AsRef<str>, as_int: bool) -> Result<String> {
1516        let bytes = hex::decode(value.as_ref()).wrap_err("Could not decode hex")?;
1517
1518        if as_int {
1519            return Ok(U256::decode(&mut &bytes[..])?.to_string());
1520        }
1521
1522        let item = Item::decode(&mut &bytes[..]).wrap_err("Could not decode rlp")?;
1523
1524        Ok(item.to_string())
1525    }
1526
1527    /// Encodes hex data or list of hex data to hexadecimal rlp
1528    ///
1529    /// # Example
1530    ///
1531    /// ```
1532    /// use cast::SimpleCast as Cast;
1533    ///
1534    /// assert_eq!(Cast::to_rlp("[]").unwrap(), "0xc0".to_string());
1535    /// assert_eq!(Cast::to_rlp("0x22").unwrap(), "0x22".to_string());
1536    /// assert_eq!(Cast::to_rlp("[\"0x61\"]",).unwrap(), "0xc161".to_string());
1537    /// assert_eq!(Cast::to_rlp("[\"0xf1\", \"f2\"]").unwrap(), "0xc481f181f2".to_string());
1538    /// # Ok::<_, eyre::Report>(())
1539    /// ```
1540    pub fn to_rlp(value: &str) -> Result<String> {
1541        let val = serde_json::from_str(value)
1542            .unwrap_or_else(|_| serde_json::Value::String(value.to_string()));
1543        let item = Item::value_to_item(&val)?;
1544        Ok(format!("0x{}", hex::encode(alloy_rlp::encode(item))))
1545    }
1546
1547    /// Converts a number of one base to another
1548    ///
1549    /// # Example
1550    ///
1551    /// ```
1552    /// use alloy_primitives::I256;
1553    /// use cast::SimpleCast as Cast;
1554    ///
1555    /// assert_eq!(Cast::to_base("100", Some("10"), "16")?, "0x64");
1556    /// assert_eq!(Cast::to_base("100", Some("10"), "oct")?, "0o144");
1557    /// assert_eq!(Cast::to_base("100", Some("10"), "binary")?, "0b1100100");
1558    ///
1559    /// assert_eq!(Cast::to_base("0xffffffffffffffff", None, "10")?, u64::MAX.to_string());
1560    /// assert_eq!(
1561    ///     Cast::to_base("0xffffffffffffffffffffffffffffffff", None, "dec")?,
1562    ///     u128::MAX.to_string()
1563    /// );
1564    /// // U256::MAX overflows as internally it is being parsed as I256
1565    /// assert_eq!(
1566    ///     Cast::to_base(
1567    ///         "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1568    ///         None,
1569    ///         "decimal"
1570    ///     )?,
1571    ///     I256::MAX.to_string()
1572    /// );
1573    /// # Ok::<_, eyre::Report>(())
1574    /// ```
1575    pub fn to_base(value: &str, base_in: Option<&str>, base_out: &str) -> Result<String> {
1576        let base_in = Base::unwrap_or_detect(base_in, value)?;
1577        let base_out: Base = base_out.parse()?;
1578        if base_in == base_out {
1579            return Ok(value.to_string());
1580        }
1581
1582        let mut n = NumberWithBase::parse_int(value, Some(&base_in.to_string()))?;
1583        n.set_base(base_out);
1584
1585        // Use Debug fmt
1586        Ok(format!("{n:#?}"))
1587    }
1588
1589    /// Converts hexdata into bytes32 value
1590    ///
1591    /// # Example
1592    ///
1593    /// ```
1594    /// use cast::SimpleCast as Cast;
1595    ///
1596    /// let bytes = Cast::to_bytes32("1234")?;
1597    /// assert_eq!(bytes, "0x1234000000000000000000000000000000000000000000000000000000000000");
1598    ///
1599    /// let bytes = Cast::to_bytes32("0x1234")?;
1600    /// assert_eq!(bytes, "0x1234000000000000000000000000000000000000000000000000000000000000");
1601    ///
1602    /// let err = Cast::to_bytes32("0x123400000000000000000000000000000000000000000000000000000000000011").unwrap_err();
1603    /// assert_eq!(err.to_string(), "string >32 bytes");
1604    /// # Ok::<_, eyre::Report>(())
1605    pub fn to_bytes32(s: &str) -> Result<String> {
1606        let s = strip_0x(s);
1607        if s.len() > 64 {
1608            eyre::bail!("string >32 bytes");
1609        }
1610
1611        let padded = format!("{s:0<64}");
1612        Ok(padded.parse::<B256>()?.to_string())
1613    }
1614
1615    /// Encodes string into bytes32 value
1616    pub fn format_bytes32_string(s: &str) -> Result<String> {
1617        let str_bytes: &[u8] = s.as_bytes();
1618        eyre::ensure!(str_bytes.len() <= 32, "bytes32 strings must not exceed 32 bytes in length");
1619
1620        let mut bytes32: [u8; 32] = [0u8; 32];
1621        bytes32[..str_bytes.len()].copy_from_slice(str_bytes);
1622        Ok(hex::encode_prefixed(bytes32))
1623    }
1624
1625    /// Decodes string from bytes32 value
1626    pub fn parse_bytes32_string(s: &str) -> Result<String> {
1627        let bytes = hex::decode(s)?;
1628        eyre::ensure!(bytes.len() == 32, "expected 32 byte hex-string");
1629        let len = bytes.iter().take_while(|x| **x != 0).count();
1630        Ok(std::str::from_utf8(&bytes[..len])?.into())
1631    }
1632
1633    /// Decodes checksummed address from bytes32 value
1634    pub fn parse_bytes32_address(s: &str) -> Result<String> {
1635        let s = strip_0x(s);
1636        if s.len() != 64 {
1637            eyre::bail!("expected 64 byte hex-string, got {s}");
1638        }
1639
1640        let s = if let Some(stripped) = s.strip_prefix("000000000000000000000000") {
1641            stripped
1642        } else {
1643            return Err(eyre::eyre!("Not convertible to address, there are non-zero bytes"));
1644        };
1645
1646        let lowercase_address_string = format!("0x{s}");
1647        let lowercase_address = Address::from_str(&lowercase_address_string)?;
1648
1649        Ok(lowercase_address.to_checksum(None))
1650    }
1651
1652    /// Decodes abi-encoded hex input or output
1653    ///
1654    /// When `input=true`, `calldata` string MUST not be prefixed with function selector
1655    ///
1656    /// # Example
1657    ///
1658    /// ```
1659    /// use cast::SimpleCast as Cast;
1660    /// use alloy_primitives::hex;
1661    ///
1662    ///     // Passing `input = false` will decode the data as the output type.
1663    ///     // The input data types and the full function sig are ignored, i.e.
1664    ///     // you could also pass `balanceOf()(uint256)` and it'd still work.
1665    ///     let data = "0x0000000000000000000000000000000000000000000000000000000000000001";
1666    ///     let sig = "balanceOf(address, uint256)(uint256)";
1667    ///     let decoded = Cast::abi_decode(sig, data, false)?[0].as_uint().unwrap().0.to_string();
1668    ///     assert_eq!(decoded, "1");
1669    ///
1670    ///     // Passing `input = true` will decode the data with the input function signature.
1671    ///     // We exclude the "prefixed" function selector from the data field (the first 4 bytes).
1672    ///     let data = "0x0000000000000000000000008dbd1b711dc621e1404633da156fcc779e1c6f3e000000000000000000000000d9f3c9cc99548bf3b44a43e0a2d07399eb918adc000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000";
1673    ///     let sig = "safeTransferFrom(address, address, uint256, uint256, bytes)";
1674    ///     let decoded = Cast::abi_decode(sig, data, true)?;
1675    ///     let decoded = [
1676    ///         decoded[0].as_address().unwrap().to_string().to_lowercase(),
1677    ///         decoded[1].as_address().unwrap().to_string().to_lowercase(),
1678    ///         decoded[2].as_uint().unwrap().0.to_string(),
1679    ///         decoded[3].as_uint().unwrap().0.to_string(),
1680    ///         hex::encode(decoded[4].as_bytes().unwrap())
1681    ///     ]
1682    ///     .into_iter()
1683    ///     .collect::<Vec<_>>();
1684    ///
1685    ///     assert_eq!(
1686    ///         decoded,
1687    ///         vec!["0x8dbd1b711dc621e1404633da156fcc779e1c6f3e", "0xd9f3c9cc99548bf3b44a43e0a2d07399eb918adc", "42", "1", ""]
1688    ///     );
1689    /// # Ok::<_, eyre::Report>(())
1690    /// ```
1691    pub fn abi_decode(sig: &str, calldata: &str, input: bool) -> Result<Vec<DynSolValue>> {
1692        foundry_common::abi::abi_decode_calldata(sig, calldata, input, false)
1693    }
1694
1695    /// Decodes calldata-encoded hex input or output
1696    ///
1697    /// Similar to `abi_decode`, but `calldata` string MUST be prefixed with function selector
1698    ///
1699    /// # Example
1700    ///
1701    /// ```
1702    /// use cast::SimpleCast as Cast;
1703    /// use alloy_primitives::hex;
1704    ///
1705    /// // Passing `input = false` will decode the data as the output type.
1706    /// // The input data types and the full function sig are ignored, i.e.
1707    /// // you could also pass `balanceOf()(uint256)` and it'd still work.
1708    /// let data = "0x0000000000000000000000000000000000000000000000000000000000000001";
1709    /// let sig = "balanceOf(address, uint256)(uint256)";
1710    /// let decoded = Cast::calldata_decode(sig, data, false)?[0].as_uint().unwrap().0.to_string();
1711    /// assert_eq!(decoded, "1");
1712    ///
1713    ///     // Passing `input = true` will decode the data with the input function signature.
1714    ///     let data = "0xf242432a0000000000000000000000008dbd1b711dc621e1404633da156fcc779e1c6f3e000000000000000000000000d9f3c9cc99548bf3b44a43e0a2d07399eb918adc000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000";
1715    ///     let sig = "safeTransferFrom(address, address, uint256, uint256, bytes)";
1716    ///     let decoded = Cast::calldata_decode(sig, data, true)?;
1717    ///     let decoded = [
1718    ///         decoded[0].as_address().unwrap().to_string().to_lowercase(),
1719    ///         decoded[1].as_address().unwrap().to_string().to_lowercase(),
1720    ///         decoded[2].as_uint().unwrap().0.to_string(),
1721    ///         decoded[3].as_uint().unwrap().0.to_string(),
1722    ///         hex::encode(decoded[4].as_bytes().unwrap()),
1723    ///    ]
1724    ///    .into_iter()
1725    ///    .collect::<Vec<_>>();
1726    ///     assert_eq!(
1727    ///         decoded,
1728    ///         vec!["0x8dbd1b711dc621e1404633da156fcc779e1c6f3e", "0xd9f3c9cc99548bf3b44a43e0a2d07399eb918adc", "42", "1", ""]
1729    ///     );
1730    /// # Ok::<_, eyre::Report>(())
1731    /// ```
1732    pub fn calldata_decode(sig: &str, calldata: &str, input: bool) -> Result<Vec<DynSolValue>> {
1733        foundry_common::abi::abi_decode_calldata(sig, calldata, input, true)
1734    }
1735
1736    /// Performs ABI encoding based off of the function signature. Does not include
1737    /// the function selector in the result.
1738    ///
1739    /// # Example
1740    ///
1741    /// ```
1742    /// use cast::SimpleCast as Cast;
1743    ///
1744    /// assert_eq!(
1745    ///     "0x0000000000000000000000000000000000000000000000000000000000000001",
1746    ///     Cast::abi_encode("f(uint a)", &["1"]).unwrap().as_str()
1747    /// );
1748    /// assert_eq!(
1749    ///     "0x0000000000000000000000000000000000000000000000000000000000000001",
1750    ///     Cast::abi_encode("constructor(uint a)", &["1"]).unwrap().as_str()
1751    /// );
1752    /// # Ok::<_, eyre::Report>(())
1753    /// ```
1754    pub fn abi_encode(sig: &str, args: &[impl AsRef<str>]) -> Result<String> {
1755        let func = get_func(sig)?;
1756        match encode_function_args(&func, args) {
1757            Ok(res) => Ok(hex::encode_prefixed(&res[4..])),
1758            Err(e) => eyre::bail!("Could not ABI encode the function and arguments. Did you pass in the right types?\nError\n{}", e),
1759        }
1760    }
1761
1762    /// Performs packed ABI encoding based off of the function signature or tuple.
1763    ///
1764    /// # Examplez
1765    ///
1766    /// ```
1767    /// use cast::SimpleCast as Cast;
1768    ///
1769    /// assert_eq!(
1770    ///     "0x0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000012c00000000000000c8",
1771    ///     Cast::abi_encode_packed("(uint128[] a, uint64 b)", &["[100, 300]", "200"]).unwrap().as_str()
1772    /// );
1773    ///
1774    /// assert_eq!(
1775    ///     "0x8dbd1b711dc621e1404633da156fcc779e1c6f3e68656c6c6f20776f726c64",
1776    ///     Cast::abi_encode_packed("foo(address a, string b)", &["0x8dbd1b711dc621e1404633da156fcc779e1c6f3e", "hello world"]).unwrap().as_str()
1777    /// );
1778    /// # Ok::<_, eyre::Report>(())
1779    /// ```
1780    pub fn abi_encode_packed(sig: &str, args: &[impl AsRef<str>]) -> Result<String> {
1781        // If the signature is a tuple, we need to prefix it to make it a function
1782        let sig =
1783            if sig.trim_start().starts_with('(') { format!("foo{sig}") } else { sig.to_string() };
1784
1785        let func = get_func(sig.as_str())?;
1786        let encoded = match encode_function_args_packed(&func, args) {
1787            Ok(res) => hex::encode(res),
1788            Err(e) => eyre::bail!("Could not ABI encode the function and arguments. Did you pass in the right types?\nError\n{}", e),
1789        };
1790        Ok(format!("0x{encoded}"))
1791    }
1792
1793    /// Performs ABI encoding to produce the hexadecimal calldata with the given arguments.
1794    ///
1795    /// # Example
1796    ///
1797    /// ```
1798    /// use cast::SimpleCast as Cast;
1799    ///
1800    /// assert_eq!(
1801    ///     "0xb3de648b0000000000000000000000000000000000000000000000000000000000000001",
1802    ///     Cast::calldata_encode("f(uint256 a)", &["1"]).unwrap().as_str()
1803    /// );
1804    /// # Ok::<_, eyre::Report>(())
1805    /// ```
1806    pub fn calldata_encode(sig: impl AsRef<str>, args: &[impl AsRef<str>]) -> Result<String> {
1807        let func = get_func(sig.as_ref())?;
1808        let calldata = encode_function_args(&func, args)?;
1809        Ok(hex::encode_prefixed(calldata))
1810    }
1811
1812    /// Returns the slot number for a given mapping key and slot.
1813    ///
1814    /// Given `mapping(k => v) m`, for a key `k` the slot number of its associated `v` is
1815    /// `keccak256(concat(h(k), p))`, where `h` is the padding function for `k`'s type, and `p`
1816    /// is slot number of the mapping `m`.
1817    ///
1818    /// See [the Solidity documentation](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html#mappings-and-dynamic-arrays)
1819    /// for more details.
1820    ///
1821    /// # Example
1822    ///
1823    /// ```
1824    /// # use cast::SimpleCast as Cast;
1825    ///
1826    /// // Value types.
1827    /// assert_eq!(
1828    ///     Cast::index("address", "0xD0074F4E6490ae3f888d1d4f7E3E43326bD3f0f5", "2").unwrap().as_str(),
1829    ///     "0x9525a448a9000053a4d151336329d6563b7e80b24f8e628e95527f218e8ab5fb"
1830    /// );
1831    /// assert_eq!(
1832    ///     Cast::index("uint256", "42", "6").unwrap().as_str(),
1833    ///     "0xfc808b0f31a1e6b9cf25ff6289feae9b51017b392cc8e25620a94a38dcdafcc1"
1834    /// );
1835    ///
1836    /// // Strings and byte arrays.
1837    /// assert_eq!(
1838    ///     Cast::index("string", "hello", "1").unwrap().as_str(),
1839    ///     "0x8404bb4d805e9ca2bd5dd5c43a107e935c8ec393caa7851b353b3192cd5379ae"
1840    /// );
1841    /// # Ok::<_, eyre::Report>(())
1842    /// ```
1843    pub fn index(key_type: &str, key: &str, slot_number: &str) -> Result<String> {
1844        let mut hasher = Keccak256::new();
1845
1846        let k_ty = DynSolType::parse(key_type).wrap_err("Could not parse type")?;
1847        let k = k_ty.coerce_str(key).wrap_err("Could not parse value")?;
1848        match k_ty {
1849            // For value types, `h` pads the value to 32 bytes in the same way as when storing the
1850            // value in memory.
1851            DynSolType::Bool |
1852            DynSolType::Int(_) |
1853            DynSolType::Uint(_) |
1854            DynSolType::FixedBytes(_) |
1855            DynSolType::Address |
1856            DynSolType::Function => hasher.update(k.as_word().unwrap()),
1857
1858            // For strings and byte arrays, `h(k)` is just the unpadded data.
1859            DynSolType::String | DynSolType::Bytes => hasher.update(k.as_packed_seq().unwrap()),
1860
1861            DynSolType::Array(..) |
1862            DynSolType::FixedArray(..) |
1863            DynSolType::Tuple(..) |
1864            DynSolType::CustomStruct { .. } => {
1865                eyre::bail!("Type `{k_ty}` is not supported as a mapping key")
1866            }
1867        }
1868
1869        let p = DynSolType::Uint(256)
1870            .coerce_str(slot_number)
1871            .wrap_err("Could not parse slot number")?;
1872        let p = p.as_word().unwrap();
1873        hasher.update(p);
1874
1875        let location = hasher.finalize();
1876        Ok(location.to_string())
1877    }
1878
1879    /// Keccak-256 hashes arbitrary data
1880    ///
1881    /// # Example
1882    ///
1883    /// ```
1884    /// use cast::SimpleCast as Cast;
1885    ///
1886    /// assert_eq!(
1887    ///     Cast::keccak("foo")?,
1888    ///     "0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d"
1889    /// );
1890    /// assert_eq!(
1891    ///     Cast::keccak("123abc")?,
1892    ///     "0xb1f1c74a1ba56f07a892ea1110a39349d40f66ca01d245e704621033cb7046a4"
1893    /// );
1894    /// assert_eq!(
1895    ///     Cast::keccak("0x12")?,
1896    ///     "0x5fa2358263196dbbf23d1ca7a509451f7a2f64c15837bfbb81298b1e3e24e4fa"
1897    /// );
1898    /// assert_eq!(
1899    ///     Cast::keccak("12")?,
1900    ///     "0x7f8b6b088b6d74c2852fc86c796dca07b44eed6fb3daf5e6b59f7c364db14528"
1901    /// );
1902    /// # Ok::<_, eyre::Report>(())
1903    /// ```
1904    pub fn keccak(data: &str) -> Result<String> {
1905        // Hex-decode if data starts with 0x.
1906        let hash =
1907            if data.starts_with("0x") { keccak256(hex::decode(data)?) } else { keccak256(data) };
1908        Ok(hash.to_string())
1909    }
1910
1911    /// Performs the left shift operation (<<) on a number
1912    ///
1913    /// # Example
1914    ///
1915    /// ```
1916    /// use cast::SimpleCast as Cast;
1917    ///
1918    /// assert_eq!(Cast::left_shift("16", "10", Some("10"), "hex")?, "0x4000");
1919    /// assert_eq!(Cast::left_shift("255", "16", Some("dec"), "hex")?, "0xff0000");
1920    /// assert_eq!(Cast::left_shift("0xff", "16", None, "hex")?, "0xff0000");
1921    /// # Ok::<_, eyre::Report>(())
1922    /// ```
1923    pub fn left_shift(
1924        value: &str,
1925        bits: &str,
1926        base_in: Option<&str>,
1927        base_out: &str,
1928    ) -> Result<String> {
1929        let base_out: Base = base_out.parse()?;
1930        let value = NumberWithBase::parse_uint(value, base_in)?;
1931        let bits = NumberWithBase::parse_uint(bits, None)?;
1932
1933        let res = value.number() << bits.number();
1934
1935        Ok(res.to_base(base_out, true)?)
1936    }
1937
1938    /// Performs the right shift operation (>>) on a number
1939    ///
1940    /// # Example
1941    ///
1942    /// ```
1943    /// use cast::SimpleCast as Cast;
1944    ///
1945    /// assert_eq!(Cast::right_shift("0x4000", "10", None, "dec")?, "16");
1946    /// assert_eq!(Cast::right_shift("16711680", "16", Some("10"), "hex")?, "0xff");
1947    /// assert_eq!(Cast::right_shift("0xff0000", "16", None, "hex")?, "0xff");
1948    /// # Ok::<(), eyre::Report>(())
1949    /// ```
1950    pub fn right_shift(
1951        value: &str,
1952        bits: &str,
1953        base_in: Option<&str>,
1954        base_out: &str,
1955    ) -> Result<String> {
1956        let base_out: Base = base_out.parse()?;
1957        let value = NumberWithBase::parse_uint(value, base_in)?;
1958        let bits = NumberWithBase::parse_uint(bits, None)?;
1959
1960        let res = value.number().wrapping_shr(bits.number().saturating_to());
1961
1962        Ok(res.to_base(base_out, true)?)
1963    }
1964
1965    /// Fetches source code of verified contracts from etherscan.
1966    ///
1967    /// # Example
1968    ///
1969    /// ```
1970    /// # use cast::SimpleCast as Cast;
1971    /// # use foundry_config::NamedChain;
1972    /// # async fn foo() -> eyre::Result<()> {
1973    /// assert_eq!(
1974    ///     "/*
1975    ///             - Bytecode Verification performed was compared on second iteration -
1976    ///             This file is part of the DAO.....",
1977    ///     Cast::etherscan_source(
1978    ///         NamedChain::Mainnet.into(),
1979    ///         "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".to_string(),
1980    ///         Some("<etherscan_api_key>".to_string()),
1981    ///         None,
1982    ///         None
1983    ///     )
1984    ///     .await
1985    ///     .unwrap()
1986    ///     .as_str()
1987    /// );
1988    /// # Ok(())
1989    /// # }
1990    /// ```
1991    pub async fn etherscan_source(
1992        chain: Chain,
1993        contract_address: String,
1994        etherscan_api_key: Option<String>,
1995        explorer_api_url: Option<String>,
1996        explorer_url: Option<String>,
1997    ) -> Result<String> {
1998        let client = explorer_client(chain, etherscan_api_key, explorer_api_url, explorer_url)?;
1999        let metadata = client.contract_source_code(contract_address.parse()?).await?;
2000        Ok(metadata.source_code())
2001    }
2002
2003    /// Fetches the source code of verified contracts from etherscan and expands the resulting
2004    /// files to a directory for easy perusal.
2005    ///
2006    /// # Example
2007    ///
2008    /// ```
2009    /// # use cast::SimpleCast as Cast;
2010    /// # use foundry_config::NamedChain;
2011    /// # use std::path::PathBuf;
2012    /// # async fn expand() -> eyre::Result<()> {
2013    /// Cast::expand_etherscan_source_to_directory(
2014    ///     NamedChain::Mainnet.into(),
2015    ///     "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".to_string(),
2016    ///     Some("<etherscan_api_key>".to_string()),
2017    ///     PathBuf::from("output_dir"),
2018    ///     None,
2019    ///     None,
2020    /// )
2021    /// .await?;
2022    /// # Ok(())
2023    /// # }
2024    /// ```
2025    pub async fn expand_etherscan_source_to_directory(
2026        chain: Chain,
2027        contract_address: String,
2028        etherscan_api_key: Option<String>,
2029        output_directory: PathBuf,
2030        explorer_api_url: Option<String>,
2031        explorer_url: Option<String>,
2032    ) -> eyre::Result<()> {
2033        let client = explorer_client(chain, etherscan_api_key, explorer_api_url, explorer_url)?;
2034        let meta = client.contract_source_code(contract_address.parse()?).await?;
2035        let source_tree = meta.source_tree();
2036        source_tree.write_to(&output_directory)?;
2037        Ok(())
2038    }
2039
2040    /// Fetches the source code of verified contracts from etherscan, flattens it and writes it to
2041    /// the given path or stdout.
2042    pub async fn etherscan_source_flatten(
2043        chain: Chain,
2044        contract_address: String,
2045        etherscan_api_key: Option<String>,
2046        output_path: Option<PathBuf>,
2047        explorer_api_url: Option<String>,
2048        explorer_url: Option<String>,
2049    ) -> Result<()> {
2050        let client = explorer_client(chain, etherscan_api_key, explorer_api_url, explorer_url)?;
2051        let metadata = client.contract_source_code(contract_address.parse()?).await?;
2052        let Some(metadata) = metadata.items.first() else {
2053            eyre::bail!("Empty contract source code")
2054        };
2055
2056        let tmp = tempfile::tempdir()?;
2057        let project = etherscan_project(metadata, tmp.path())?;
2058        let target_path = project.find_contract_path(&metadata.contract_name)?;
2059
2060        let flattened = Flattener::new(project, &target_path)?.flatten();
2061
2062        if let Some(path) = output_path {
2063            fs::create_dir_all(path.parent().unwrap())?;
2064            fs::write(&path, flattened)?;
2065            sh_println!("Flattened file written at {}", path.display())?
2066        } else {
2067            sh_println!("{flattened}")?
2068        }
2069
2070        Ok(())
2071    }
2072
2073    /// Disassembles hex encoded bytecode into individual / human readable opcodes
2074    ///
2075    /// # Example
2076    ///
2077    /// ```
2078    /// use alloy_primitives::hex;
2079    /// use cast::SimpleCast as Cast;
2080    ///
2081    /// # async fn foo() -> eyre::Result<()> {
2082    /// let bytecode = "0x608060405260043610603f57600035";
2083    /// let opcodes = Cast::disassemble(&hex::decode(bytecode)?)?;
2084    /// println!("{}", opcodes);
2085    /// # Ok(())
2086    /// # }
2087    /// ```
2088    pub fn disassemble(code: &[u8]) -> Result<String> {
2089        let mut output = String::new();
2090
2091        for step in decode_instructions(code)? {
2092            write!(output, "{:08x}: ", step.pc)?;
2093
2094            if let Some(op) = step.op {
2095                write!(output, "{op}")?;
2096            } else {
2097                write!(output, "INVALID")?;
2098            }
2099
2100            if !step.immediate.is_empty() {
2101                write!(output, " {}", hex::encode_prefixed(step.immediate))?;
2102            }
2103
2104            writeln!(output)?;
2105        }
2106
2107        Ok(output)
2108    }
2109
2110    /// Gets the selector for a given function signature
2111    /// Optimizes if the `optimize` parameter is set to a number of leading zeroes
2112    ///
2113    /// # Example
2114    ///
2115    /// ```
2116    /// use cast::SimpleCast as Cast;
2117    ///
2118    /// assert_eq!(Cast::get_selector("foo(address,uint256)", 0)?.0, String::from("0xbd0d639f"));
2119    /// # Ok::<(), eyre::Error>(())
2120    /// ```
2121    pub fn get_selector(signature: &str, optimize: usize) -> Result<(String, String)> {
2122        if optimize > 4 {
2123            eyre::bail!("number of leading zeroes must not be greater than 4");
2124        }
2125        if optimize == 0 {
2126            let selector = get_func(signature)?.selector();
2127            return Ok((selector.to_string(), String::from(signature)));
2128        }
2129        let Some((name, params)) = signature.split_once('(') else {
2130            eyre::bail!("invalid function signature");
2131        };
2132
2133        let num_threads = std::thread::available_parallelism().map_or(1, |n| n.get());
2134        let found = AtomicBool::new(false);
2135
2136        let result: Option<(u32, String, String)> =
2137            (0..num_threads).into_par_iter().find_map_any(|i| {
2138                let nonce_start = i as u32;
2139                let nonce_step = num_threads as u32;
2140
2141                let mut nonce = nonce_start;
2142                while nonce < u32::MAX && !found.load(Ordering::Relaxed) {
2143                    let input = format!("{name}{nonce}({params}");
2144                    let hash = keccak256(input.as_bytes());
2145                    let selector = &hash[..4];
2146
2147                    if selector.iter().take_while(|&&byte| byte == 0).count() == optimize {
2148                        found.store(true, Ordering::Relaxed);
2149                        return Some((nonce, hex::encode_prefixed(selector), input));
2150                    }
2151
2152                    nonce += nonce_step;
2153                }
2154                None
2155            });
2156
2157        match result {
2158            Some((_nonce, selector, signature)) => Ok((selector, signature)),
2159            None => eyre::bail!("No selector found"),
2160        }
2161    }
2162
2163    /// Extracts function selectors, arguments and state mutability from bytecode
2164    ///
2165    /// # Example
2166    ///
2167    /// ```
2168    /// use alloy_primitives::fixed_bytes;
2169    /// use cast::SimpleCast as Cast;
2170    ///
2171    /// let bytecode = "6080604052348015600e575f80fd5b50600436106026575f3560e01c80632125b65b14602a575b5f80fd5b603a6035366004603c565b505050565b005b5f805f60608486031215604d575f80fd5b833563ffffffff81168114605f575f80fd5b925060208401356001600160a01b03811681146079575f80fd5b915060408401356001600160e01b03811681146093575f80fd5b80915050925092509256";
2172    /// let functions = Cast::extract_functions(bytecode)?;
2173    /// assert_eq!(functions, vec![(fixed_bytes!("0x2125b65b"), "uint32,address,uint224".to_string(), "pure")]);
2174    /// # Ok::<(), eyre::Report>(())
2175    /// ```
2176    pub fn extract_functions(bytecode: &str) -> Result<Vec<(Selector, String, &str)>> {
2177        let code = hex::decode(bytecode)?;
2178        let info = evmole::contract_info(
2179            evmole::ContractInfoArgs::new(&code)
2180                .with_selectors()
2181                .with_arguments()
2182                .with_state_mutability(),
2183        );
2184        Ok(info
2185            .functions
2186            .expect("functions extraction was requested")
2187            .into_iter()
2188            .map(|f| {
2189                (
2190                    f.selector.into(),
2191                    f.arguments
2192                        .expect("arguments extraction was requested")
2193                        .into_iter()
2194                        .map(|t| t.sol_type_name().to_string())
2195                        .collect::<Vec<String>>()
2196                        .join(","),
2197                    f.state_mutability
2198                        .expect("state_mutability extraction was requested")
2199                        .as_json_str(),
2200                )
2201            })
2202            .collect())
2203    }
2204
2205    /// Decodes a raw EIP2718 transaction payload
2206    /// Returns details about the typed transaction and ECSDA signature components
2207    ///
2208    /// # Example
2209    ///
2210    /// ```
2211    /// use cast::SimpleCast as Cast;
2212    ///
2213    /// let tx = "0x02f8f582a86a82058d8459682f008508351050808303fd84948e42f2f4101563bf679975178e880fd87d3efd4e80b884659ac74b00000000000000000000000080f0c1c49891dcfdd40b6e0f960f84e6042bcb6f000000000000000000000000b97ef9ef8734c71904d8002f8b6bc66dd9c48a6e00000000000000000000000000000000000000000000000000000000007ff4e20000000000000000000000000000000000000000000000000000000000000064c001a05d429597befe2835396206781b199122f2e8297327ed4a05483339e7a8b2022aa04c23a7f70fb29dda1b4ee342fb10a625e9b8ddc6a603fb4e170d4f6f37700cb8";
2214    /// let tx_envelope = Cast::decode_raw_transaction(&tx)?;
2215    /// # Ok::<(), eyre::Report>(())
2216    pub fn decode_raw_transaction(tx: &str) -> Result<TxEnvelope> {
2217        let tx_hex = hex::decode(tx)?;
2218        let tx = TxEnvelope::decode_2718(&mut tx_hex.as_slice())?;
2219        Ok(tx)
2220    }
2221}
2222
2223fn strip_0x(s: &str) -> &str {
2224    s.strip_prefix("0x").unwrap_or(s)
2225}
2226
2227fn explorer_client(
2228    chain: Chain,
2229    api_key: Option<String>,
2230    api_url: Option<String>,
2231    explorer_url: Option<String>,
2232) -> Result<Client> {
2233    let mut builder = Client::builder().with_chain_id(chain);
2234
2235    let deduced = chain.etherscan_urls();
2236
2237    let explorer_url = explorer_url
2238        .or(deduced.map(|d| d.1.to_string()))
2239        .ok_or_eyre("Please provide the explorer browser URL using `--explorer-url`")?;
2240    builder = builder.with_url(explorer_url)?;
2241
2242    let api_url = api_url
2243        .or(deduced.map(|d| d.0.to_string()))
2244        .ok_or_eyre("Please provide the explorer API URL using `--explorer-api-url`")?;
2245    builder = builder.with_api_url(api_url)?;
2246
2247    if let Some(api_key) = api_key {
2248        builder = builder.with_api_key(api_key);
2249    }
2250
2251    builder.build().map_err(Into::into)
2252}
2253
2254#[cfg(test)]
2255mod tests {
2256    use super::SimpleCast as Cast;
2257    use alloy_primitives::hex;
2258
2259    #[test]
2260    fn simple_selector() {
2261        assert_eq!("0xc2985578", Cast::get_selector("foo()", 0).unwrap().0.as_str())
2262    }
2263
2264    #[test]
2265    fn selector_with_arg() {
2266        assert_eq!("0xbd0d639f", Cast::get_selector("foo(address,uint256)", 0).unwrap().0.as_str())
2267    }
2268
2269    #[test]
2270    fn calldata_uint() {
2271        assert_eq!(
2272            "0xb3de648b0000000000000000000000000000000000000000000000000000000000000001",
2273            Cast::calldata_encode("f(uint256 a)", &["1"]).unwrap().as_str()
2274        );
2275    }
2276
2277    // <https://github.com/foundry-rs/foundry/issues/2681>
2278    #[test]
2279    fn calldata_array() {
2280        assert_eq!(
2281            "0xcde2baba0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000",
2282            Cast::calldata_encode("propose(string[])", &["[\"\"]"]).unwrap().as_str()
2283        );
2284    }
2285
2286    #[test]
2287    fn calldata_bool() {
2288        assert_eq!(
2289            "0x6fae94120000000000000000000000000000000000000000000000000000000000000000",
2290            Cast::calldata_encode("bar(bool)", &["false"]).unwrap().as_str()
2291        );
2292    }
2293
2294    #[test]
2295    fn abi_decode() {
2296        let data = "0x0000000000000000000000000000000000000000000000000000000000000001";
2297        let sig = "balanceOf(address, uint256)(uint256)";
2298        assert_eq!(
2299            "1",
2300            Cast::abi_decode(sig, data, false).unwrap()[0].as_uint().unwrap().0.to_string()
2301        );
2302
2303        let data = "0x0000000000000000000000008dbd1b711dc621e1404633da156fcc779e1c6f3e000000000000000000000000d9f3c9cc99548bf3b44a43e0a2d07399eb918adc000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000";
2304        let sig = "safeTransferFrom(address,address,uint256,uint256,bytes)";
2305        let decoded = Cast::abi_decode(sig, data, true).unwrap();
2306        let decoded = [
2307            decoded[0]
2308                .as_address()
2309                .unwrap()
2310                .to_string()
2311                .strip_prefix("0x")
2312                .unwrap()
2313                .to_owned()
2314                .to_lowercase(),
2315            decoded[1]
2316                .as_address()
2317                .unwrap()
2318                .to_string()
2319                .strip_prefix("0x")
2320                .unwrap()
2321                .to_owned()
2322                .to_lowercase(),
2323            decoded[2].as_uint().unwrap().0.to_string(),
2324            decoded[3].as_uint().unwrap().0.to_string(),
2325            hex::encode(decoded[4].as_bytes().unwrap()),
2326        ]
2327        .to_vec();
2328        assert_eq!(
2329            decoded,
2330            vec![
2331                "8dbd1b711dc621e1404633da156fcc779e1c6f3e",
2332                "d9f3c9cc99548bf3b44a43e0a2d07399eb918adc",
2333                "42",
2334                "1",
2335                ""
2336            ]
2337        );
2338    }
2339
2340    #[test]
2341    fn calldata_decode() {
2342        let data = "0x0000000000000000000000000000000000000000000000000000000000000001";
2343        let sig = "balanceOf(address, uint256)(uint256)";
2344        let decoded =
2345            Cast::calldata_decode(sig, data, false).unwrap()[0].as_uint().unwrap().0.to_string();
2346        assert_eq!(decoded, "1");
2347
2348        // Passing `input = true` will decode the data with the input function signature.
2349        // We exclude the "prefixed" function selector from the data field (the first 4 bytes).
2350        let data = "0xf242432a0000000000000000000000008dbd1b711dc621e1404633da156fcc779e1c6f3e000000000000000000000000d9f3c9cc99548bf3b44a43e0a2d07399eb918adc000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000";
2351        let sig = "safeTransferFrom(address, address, uint256, uint256, bytes)";
2352        let decoded = Cast::calldata_decode(sig, data, true).unwrap();
2353        let decoded = [
2354            decoded[0].as_address().unwrap().to_string().to_lowercase(),
2355            decoded[1].as_address().unwrap().to_string().to_lowercase(),
2356            decoded[2].as_uint().unwrap().0.to_string(),
2357            decoded[3].as_uint().unwrap().0.to_string(),
2358            hex::encode(decoded[4].as_bytes().unwrap()),
2359        ]
2360        .into_iter()
2361        .collect::<Vec<_>>();
2362        assert_eq!(
2363            decoded,
2364            vec![
2365                "0x8dbd1b711dc621e1404633da156fcc779e1c6f3e",
2366                "0xd9f3c9cc99548bf3b44a43e0a2d07399eb918adc",
2367                "42",
2368                "1",
2369                ""
2370            ]
2371        );
2372    }
2373
2374    #[test]
2375    fn concat_hex() {
2376        assert_eq!(Cast::concat_hex(["0x00", "0x01"]), "0x0001");
2377        assert_eq!(Cast::concat_hex(["1", "2"]), "0x12");
2378    }
2379
2380    #[test]
2381    fn from_rlp() {
2382        let rlp = "0xf8b1a02b5df5f0757397573e8ff34a8b987b21680357de1f6c8d10273aa528a851eaca8080a02838ac1d2d2721ba883169179b48480b2ba4f43d70fcf806956746bd9e83f90380a0e46fff283b0ab96a32a7cc375cecc3ed7b6303a43d64e0a12eceb0bc6bd8754980a01d818c1c414c665a9c9a0e0c0ef1ef87cacb380b8c1f6223cb2a68a4b2d023f5808080a0236e8f61ecde6abfebc6c529441f782f62469d8a2cc47b7aace2c136bd3b1ff08080808080";
2383        let item = Cast::from_rlp(rlp, false).unwrap();
2384        assert_eq!(
2385            item,
2386            r#"["0x2b5df5f0757397573e8ff34a8b987b21680357de1f6c8d10273aa528a851eaca","0x","0x","0x2838ac1d2d2721ba883169179b48480b2ba4f43d70fcf806956746bd9e83f903","0x","0xe46fff283b0ab96a32a7cc375cecc3ed7b6303a43d64e0a12eceb0bc6bd87549","0x","0x1d818c1c414c665a9c9a0e0c0ef1ef87cacb380b8c1f6223cb2a68a4b2d023f5","0x","0x","0x","0x236e8f61ecde6abfebc6c529441f782f62469d8a2cc47b7aace2c136bd3b1ff0","0x","0x","0x","0x","0x"]"#
2387        )
2388    }
2389
2390    #[test]
2391    fn disassemble_incomplete_sequence() {
2392        let incomplete = &hex!("60"); // PUSH1
2393        let disassembled = Cast::disassemble(incomplete).unwrap();
2394        assert_eq!(disassembled, "00000000: PUSH1 0x00\n");
2395
2396        let complete = &hex!("6000"); // PUSH1 0x00
2397        let disassembled = Cast::disassemble(complete);
2398        assert!(disassembled.is_ok());
2399
2400        let incomplete = &hex!("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // PUSH32 with 31 bytes
2401
2402        let disassembled = Cast::disassemble(incomplete).unwrap();
2403
2404        assert_eq!(
2405            disassembled,
2406            "00000000: PUSH32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00\n"
2407        );
2408
2409        let complete = &hex!("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // PUSH32 with 32 bytes
2410        let disassembled = Cast::disassemble(complete);
2411        assert!(disassembled.is_ok());
2412    }
2413}