alloy_provider/ext/
anvil.rs

1//! This module extends the Ethereum JSON-RPC provider with the Anvil namespace's RPC methods.
2
3use crate::{PendingTransactionBuilder, Provider};
4use alloy_consensus::Blob;
5use alloy_network::{Network, TransactionBuilder};
6use alloy_primitives::{Address, Bytes, TxHash, B256, U128, U256, U64};
7use alloy_rpc_types_anvil::{Forking, Metadata, MineOptions, NodeInfo, ReorgOptions};
8use alloy_rpc_types_eth::Block;
9use alloy_transport::{TransportError, TransportResult};
10use futures::try_join;
11
12/// Anvil namespace rpc interface that gives access to several non-standard RPC methods.
13#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
14#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
15pub trait AnvilApi<N: Network>: Send + Sync {
16    // Not implemented:
17    // - anvil_enable_traces: Not implemented in the Anvil RPC API.
18    // - anvil_set_block: Not implemented / wired correctly in the Anvil RPC API.
19
20    /// Send transactions impersonating specific account and contract addresses.
21    async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()>;
22
23    /// Stops impersonating an account if previously set with `anvil_impersonateAccount`.
24    async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()>;
25
26    /// If set to true will make every account impersonated.
27    async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()>;
28
29    /// Impersonates the `from` address in the given transaction request, optionally funds the
30    /// sender, sends the transaction, and optionally stops impersonating after execution based
31    /// on the provided config.
32    async fn anvil_send_impersonated_transaction_with_config(
33        &self,
34        request: N::TransactionRequest,
35        config: ImpersonateConfig,
36    ) -> TransportResult<PendingTransactionBuilder<N>>;
37
38    /// Returns true if auto mining is enabled, and false.
39    async fn anvil_get_auto_mine(&self) -> TransportResult<bool>;
40
41    /// Enables or disables, based on the single boolean argument, the automatic mining of new
42    /// blocks with each new transaction submitted to the network.
43    async fn anvil_set_auto_mine(&self, enable_automine: bool) -> TransportResult<()>;
44
45    /// Mines a series of blocks.
46    async fn anvil_mine(
47        &self,
48        num_blocks: Option<u64>,
49        interval: Option<u64>,
50    ) -> TransportResult<()>;
51
52    /// Sets the mining behavior to interval with the given interval (seconds).
53    async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()>;
54
55    /// Removes transactions from the pool.
56    async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>>;
57
58    /// Removes all transactions from the pool.
59    async fn anvil_drop_all_transactions(&self) -> TransportResult<()>;
60
61    /// Reset the fork to a fresh forked state, and optionally update the fork config.
62    ///
63    /// If `forking` is `None` then this will disable forking entirely.
64    async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()>;
65
66    /// Sets the chain ID.
67    async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()>;
68
69    /// Modifies the balance of an account.
70    async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()>;
71
72    /// Sets the code of a contract.
73    async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()>;
74
75    /// Sets the nonce of an address.
76    async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()>;
77
78    /// Writes a single slot of the account's storage.
79    async fn anvil_set_storage_at(
80        &self,
81        address: Address,
82        slot: U256,
83        val: B256,
84    ) -> TransportResult<bool>;
85
86    /// Enable or disable logging.
87    async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()>;
88
89    /// Set the minimum gas price for the node.
90    async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()>;
91
92    /// Sets the base fee of the next block.
93    async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()>;
94
95    /// Sets the coinbase address.
96    async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()>;
97
98    /// Create a buffer that represents all state on the chain, which can be loaded to separate
99    /// process by calling `anvil_loadState`
100    async fn anvil_dump_state(&self) -> TransportResult<Bytes>;
101
102    /// Append chain state buffer to current chain. Will overwrite any conflicting addresses or
103    /// storage.
104    async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool>;
105
106    /// Retrieves the Anvil node configuration params.
107    async fn anvil_node_info(&self) -> TransportResult<NodeInfo>;
108
109    /// Retrieves metadata about the Anvil instance.
110    async fn anvil_metadata(&self) -> TransportResult<Metadata>;
111
112    /// Removes all transactions from the pool for a specific address.
113    async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()>;
114
115    /// Snapshot the state of the blockchain at the current block.
116    async fn anvil_snapshot(&self) -> TransportResult<U256>;
117
118    /// Revert the state of the blockchain to a previous snapshot.
119    /// Takes a single parameter, which is the snapshot id to revert to.
120    async fn anvil_revert(&self, id: U256) -> TransportResult<bool>;
121
122    /// Jump forward in time by the given amount of time, in seconds.
123    async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64>;
124
125    /// Similar to `evm_increaseTime` but takes the exact timestamp that you want in the next block.
126    async fn anvil_set_next_block_timestamp(&self, timestamp: u64) -> TransportResult<()>;
127
128    /// Sets the specific timestamp and returns the number of seconds between the given timestamp
129    /// and the current time.
130    async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64>;
131
132    /// Set the next block gas limit.
133    async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool>;
134
135    /// Sets an interval for the block timestamp.
136    async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()>;
137
138    /// Unsets the interval for the block timestamp.
139    async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool>;
140
141    /// Mine blocks, instantly.
142    /// This will mine the blocks regardless of the configured mining mode.
143    async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String>;
144
145    /// Mine blocks, instantly and return the mined blocks.
146    /// This will mine the blocks regardless of the configured mining mode.
147    async fn anvil_mine_detailed(&self, opts: Option<MineOptions>) -> TransportResult<Vec<Block>>;
148
149    /// Sets the backend rpc url.
150    async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()>;
151
152    /// Reorg the chain
153    async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()>;
154
155    /// Rollback the chain  
156    async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()>;
157
158    /// Retrieves a blob by its versioned hash.
159    async fn anvil_get_blob_by_versioned_hash(
160        &self,
161        versioned_hash: B256,
162    ) -> TransportResult<Option<Blob>>;
163
164    /// Retrieves blobs by transaction hash.
165    async fn anvil_get_blobs_by_tx_hash(
166        &self,
167        tx_hash: TxHash,
168    ) -> TransportResult<Option<Vec<Blob>>>;
169
170    /// Execute a transaction regardless of signature status.
171    async fn eth_send_unsigned_transaction(
172        &self,
173        request: N::TransactionRequest,
174    ) -> TransportResult<TxHash>;
175
176    /// Executes a transaction and waits for it to be mined, returning the receipt.
177    async fn eth_send_transaction_sync(
178        &self,
179        request: N::TransactionRequest,
180    ) -> TransportResult<N::ReceiptResponse>;
181
182    /// Sends a raw transaction and waits for it to be mined, returning the receipt.
183    async fn eth_send_raw_transaction_sync(
184        &self,
185        request: Bytes,
186    ) -> TransportResult<N::ReceiptResponse>;
187
188    /// Sets impersonated transaction
189    async fn anvil_send_impersonated_transaction(
190        &self,
191        request: N::TransactionRequest,
192    ) -> TransportResult<TxHash>;
193
194    /// Modifies the ERC20 balance of an account.
195    async fn anvil_deal_erc20(
196        &self,
197        address: Address,
198        token_address: Address,
199        balance: U256,
200    ) -> TransportResult<()>;
201
202    /// Modifies the ERC20 allowance of an account.
203    async fn anvil_set_erc20_allowance(
204        &self,
205        owner: Address,
206        spender: Address,
207        token: Address,
208        allowance: U256,
209    ) -> TransportResult<()>;
210}
211
212#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
213#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
214impl<N, P> AnvilApi<N> for P
215where
216    N: Network,
217    P: Provider<N>,
218{
219    async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()> {
220        self.client().request("anvil_impersonateAccount", (address,)).await
221    }
222
223    async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()> {
224        self.client().request("anvil_stopImpersonatingAccount", (address,)).await
225    }
226
227    async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()> {
228        self.client().request("anvil_autoImpersonateAccount", (enabled,)).await
229    }
230
231    async fn anvil_get_auto_mine(&self) -> TransportResult<bool> {
232        self.client().request_noparams("anvil_getAutomine").await
233    }
234
235    async fn anvil_set_auto_mine(&self, enabled: bool) -> TransportResult<()> {
236        self.client().request("anvil_setAutomine", (enabled,)).await
237    }
238
239    async fn anvil_mine(
240        &self,
241        num_blocks: Option<u64>,
242        interval: Option<u64>,
243    ) -> TransportResult<()> {
244        self.client()
245            .request("anvil_mine", (num_blocks.map(U64::from), interval.map(U64::from)))
246            .await
247    }
248
249    async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()> {
250        self.client().request("anvil_setIntervalMining", (secs,)).await
251    }
252
253    async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>> {
254        self.client().request("anvil_dropTransaction", (tx_hash,)).await
255    }
256
257    async fn anvil_drop_all_transactions(&self) -> TransportResult<()> {
258        self.client().request_noparams("anvil_dropAllTransactions").await
259    }
260
261    async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()> {
262        self.client().request("anvil_reset", (forking,)).await
263    }
264
265    async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()> {
266        self.client().request("anvil_setChainId", (chain_id,)).await
267    }
268
269    async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()> {
270        self.client().request("anvil_setBalance", (address, balance)).await
271    }
272
273    async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()> {
274        self.client().request("anvil_setCode", (address, code)).await
275    }
276
277    async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()> {
278        self.client().request("anvil_setNonce", (address, U64::from(nonce))).await
279    }
280
281    async fn anvil_set_storage_at(
282        &self,
283        address: Address,
284        slot: U256,
285        val: B256,
286    ) -> TransportResult<bool> {
287        self.client().request("anvil_setStorageAt", (address, slot, val)).await
288    }
289
290    async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()> {
291        self.client().request("anvil_setLoggingEnabled", (enable,)).await
292    }
293
294    async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()> {
295        self.client().request("anvil_setMinGasPrice", (U128::from(gas),)).await
296    }
297
298    async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()> {
299        self.client().request("anvil_setNextBlockBaseFeePerGas", (U128::from(basefee),)).await
300    }
301
302    async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()> {
303        self.client().request("anvil_setCoinbase", (address,)).await
304    }
305
306    async fn anvil_dump_state(&self) -> TransportResult<Bytes> {
307        self.client().request_noparams("anvil_dumpState").await
308    }
309
310    async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool> {
311        self.client().request("anvil_loadState", (buf,)).await
312    }
313
314    async fn anvil_node_info(&self) -> TransportResult<NodeInfo> {
315        self.client().request_noparams("anvil_nodeInfo").await
316    }
317
318    async fn anvil_metadata(&self) -> TransportResult<Metadata> {
319        self.client().request_noparams("anvil_metadata").await
320    }
321
322    async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()> {
323        self.client().request("anvil_removePoolTransactions", (address,)).await
324    }
325
326    async fn anvil_snapshot(&self) -> TransportResult<U256> {
327        self.client().request_noparams("evm_snapshot").await
328    }
329
330    async fn anvil_revert(&self, id: U256) -> TransportResult<bool> {
331        self.client().request("evm_revert", (id,)).await
332    }
333
334    async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64> {
335        self.client().request("evm_increaseTime", (U64::from(seconds),)).await
336    }
337
338    async fn anvil_set_next_block_timestamp(&self, seconds: u64) -> TransportResult<()> {
339        self.client().request("evm_setNextBlockTimestamp", (seconds,)).await
340    }
341
342    async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64> {
343        self.client().request("evm_setTime", (timestamp,)).await
344    }
345
346    async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool> {
347        self.client().request("evm_setBlockGasLimit", (U64::from(gas_limit),)).await
348    }
349
350    async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()> {
351        self.client().request("anvil_setBlockTimestampInterval", (seconds,)).await
352    }
353
354    async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool> {
355        self.client().request_noparams("anvil_removeBlockTimestampInterval").await
356    }
357
358    async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String> {
359        self.client().request("evm_mine", (opts,)).await
360    }
361
362    async fn anvil_mine_detailed(&self, opts: Option<MineOptions>) -> TransportResult<Vec<Block>> {
363        self.client().request("evm_mine_detailed", (opts,)).await
364    }
365
366    async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()> {
367        self.client().request("anvil_setRpcUrl", (url,)).await
368    }
369
370    async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()> {
371        self.client().request("anvil_reorg", options).await
372    }
373
374    async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()> {
375        self.client().request("anvil_rollback", (depth,)).await
376    }
377
378    async fn anvil_get_blob_by_versioned_hash(&self, hash: B256) -> TransportResult<Option<Blob>> {
379        self.client().request("anvil_getBlobByHash", (hash,)).await
380    }
381
382    async fn anvil_get_blobs_by_tx_hash(&self, hash: TxHash) -> TransportResult<Option<Vec<Blob>>> {
383        self.client().request("anvil_getBlobsByTransactionHash", (hash,)).await
384    }
385
386    async fn eth_send_unsigned_transaction(
387        &self,
388        request: N::TransactionRequest,
389    ) -> TransportResult<TxHash> {
390        self.client().request("eth_sendUnsignedTransaction", (request,)).await
391    }
392
393    async fn eth_send_transaction_sync(
394        &self,
395        request: N::TransactionRequest,
396    ) -> TransportResult<N::ReceiptResponse> {
397        self.client().request("eth_sendTransactionSync", (request,)).await
398    }
399
400    async fn eth_send_raw_transaction_sync(
401        &self,
402        request: Bytes,
403    ) -> TransportResult<N::ReceiptResponse> {
404        self.client().request("eth_sendRawTransactionSync", (request,)).await
405    }
406
407    async fn anvil_send_impersonated_transaction(
408        &self,
409        request: N::TransactionRequest,
410    ) -> TransportResult<TxHash> {
411        self.client().request("eth_sendTransaction", (request,)).await
412    }
413
414    async fn anvil_deal_erc20(
415        &self,
416        address: Address,
417        token_address: Address,
418        balance: U256,
419    ) -> TransportResult<()> {
420        self.client().request("anvil_dealERC20", (address, token_address, balance)).await
421    }
422
423    async fn anvil_set_erc20_allowance(
424        &self,
425        owner: Address,
426        spender: Address,
427        token: Address,
428        allowance: U256,
429    ) -> TransportResult<()> {
430        self.client().request("anvil_setERC20Allowance", (owner, spender, token, allowance)).await
431    }
432
433    async fn anvil_send_impersonated_transaction_with_config(
434        &self,
435        request: N::TransactionRequest,
436        config: ImpersonateConfig,
437    ) -> TransportResult<PendingTransactionBuilder<N>> {
438        let from = request.from().ok_or_else(|| {
439            TransportError::from(alloy_transport::TransportErrorKind::Custom(
440                "TransactionRequest must have a `from` address set.".to_string().into(),
441            ))
442        })?;
443
444        let impersonate_future = self.anvil_impersonate_account(from);
445
446        if let Some(amount) = config.fund_amount {
447            let fund_future = self.anvil_set_balance(from, amount);
448            try_join!(fund_future, impersonate_future)?;
449        } else {
450            impersonate_future.await?;
451        }
452
453        let tx_hash = self.anvil_send_impersonated_transaction(request).await?;
454        let pending = PendingTransactionBuilder::new(self.root().clone(), tx_hash);
455
456        if config.stop_impersonate {
457            self.anvil_stop_impersonating_account(from).await?;
458        }
459
460        Ok(pending)
461    }
462}
463
464/// Configuration for impersonated transactions, including optional funding and whether to stop
465/// impersonation.
466#[derive(Debug, Clone)]
467pub struct ImpersonateConfig {
468    /// Optional amount of ETH to fund the impersonated account.
469    pub fund_amount: Option<U256>,
470    /// Whether to stop impersonating after the transaction is sent.
471    pub stop_impersonate: bool,
472}
473
474impl Default for ImpersonateConfig {
475    fn default() -> Self {
476        Self { fund_amount: None, stop_impersonate: true }
477    }
478}
479
480impl ImpersonateConfig {
481    /// Set the impersonation to continue after the transaction.
482    pub const fn keep_impersonate(mut self) -> Self {
483        self.stop_impersonate = false;
484        self
485    }
486
487    /// Set the impersonation to stop after the transaction.
488    pub const fn stop_impersonate(mut self) -> Self {
489        self.stop_impersonate = true;
490        self
491    }
492
493    /// Set the funding amount for the impersonated account.
494    pub const fn fund(mut self, amount: U256) -> Self {
495        self.fund_amount = Some(amount);
496        self
497    }
498
499    /// Clear the funding amount.
500    pub const fn no_fund(mut self) -> Self {
501        self.fund_amount = None;
502        self
503    }
504}
505
506#[cfg(test)]
507mod tests {
508    use super::*;
509    use crate::{
510        fillers::{ChainIdFiller, GasFiller},
511        ProviderBuilder,
512    };
513    use alloy_consensus::{SidecarBuilder, SimpleCoder};
514    use alloy_eips::BlockNumberOrTag;
515    use alloy_network::{TransactionBuilder, TransactionBuilder4844};
516    use alloy_primitives::{address, B256};
517    use alloy_rpc_types_eth::TransactionRequest;
518    use alloy_sol_types::{sol, SolCall};
519
520    // use alloy_node_bindings::Anvil; (to be used in `test_anvil_reset`)
521    const FORK_URL: &str = "https://reth-ethereum.ithaca.xyz/rpc";
522
523    #[tokio::test]
524    async fn test_anvil_impersonate_account_stop_impersonating_account() {
525        let provider = ProviderBuilder::new()
526            .disable_recommended_fillers()
527            .with_simple_nonce_management()
528            .filler(GasFiller)
529            .filler(ChainIdFiller::default())
530            .connect_anvil();
531
532        let impersonate = Address::random();
533        let to = Address::random();
534        let val = U256::from(1337);
535        let funding = U256::from(1e18 as u64);
536
537        provider.anvil_set_balance(impersonate, funding).await.unwrap();
538
539        let balance = provider.get_balance(impersonate).await.unwrap();
540        assert_eq!(balance, funding);
541
542        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
543
544        let res = provider.send_transaction(tx.clone()).await;
545        res.unwrap_err();
546
547        provider.anvil_impersonate_account(impersonate).await.unwrap();
548        assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
549
550        let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
551        assert_eq!(res.from, impersonate);
552
553        let nonce = provider.get_transaction_count(impersonate).await.unwrap();
554        assert_eq!(nonce, 1);
555
556        let balance = provider.get_balance(to).await.unwrap();
557        assert_eq!(balance, val);
558
559        provider.anvil_stop_impersonating_account(impersonate).await.unwrap();
560        let res = provider.send_transaction(tx).await;
561        res.unwrap_err();
562    }
563
564    #[tokio::test]
565    async fn test_anvil_impersonated_send_with_config() {
566        let provider = ProviderBuilder::new()
567            .disable_recommended_fillers()
568            .with_simple_nonce_management()
569            .filler(GasFiller)
570            .filler(ChainIdFiller::default())
571            .connect_anvil();
572
573        let impersonate = Address::random();
574        let to = Address::random();
575        let val = U256::from(1337);
576        let funding = U256::from(1e18 as u64);
577
578        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
579
580        let config = ImpersonateConfig { fund_amount: Some(funding), stop_impersonate: true };
581
582        let pending = provider
583            .anvil_send_impersonated_transaction_with_config(tx.clone(), config)
584            .await
585            .expect("impersonated send failed");
586        let receipt = pending.get_receipt().await.unwrap();
587        assert_eq!(receipt.from, impersonate);
588
589        let recipient_balance = provider.get_balance(to).await.unwrap();
590        assert_eq!(recipient_balance, val);
591    }
592
593    #[tokio::test]
594    async fn test_anvil_auto_impersonate_account() {
595        let provider = ProviderBuilder::new()
596            .disable_recommended_fillers()
597            .with_simple_nonce_management()
598            .filler(GasFiller)
599            .filler(ChainIdFiller::default())
600            .connect_anvil();
601
602        let impersonate = Address::random();
603        let to = Address::random();
604        let val = U256::from(1337);
605        let funding = U256::from(1e18 as u64);
606
607        provider.anvil_set_balance(impersonate, funding).await.unwrap();
608
609        let balance = provider.get_balance(impersonate).await.unwrap();
610        assert_eq!(balance, funding);
611
612        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
613
614        let res = provider.send_transaction(tx.clone()).await;
615        res.unwrap_err();
616
617        provider.anvil_auto_impersonate_account(true).await.unwrap();
618
619        let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
620        assert_eq!(res.from, impersonate);
621
622        let nonce = provider.get_transaction_count(impersonate).await.unwrap();
623        assert_eq!(nonce, 1);
624
625        let balance = provider.get_balance(to).await.unwrap();
626        assert_eq!(balance, val);
627
628        provider.anvil_auto_impersonate_account(false).await.unwrap();
629        let res = provider.send_transaction(tx).await;
630        res.unwrap_err();
631
632        provider.anvil_impersonate_account(impersonate).await.unwrap();
633        assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
634    }
635
636    #[tokio::test]
637    async fn test_anvil_get_auto_mine_set_auto_mine() {
638        let provider = ProviderBuilder::new().connect_anvil();
639
640        provider.anvil_set_auto_mine(false).await.unwrap();
641
642        let enabled = provider.anvil_get_auto_mine().await.unwrap();
643        assert!(!enabled);
644
645        provider.anvil_set_auto_mine(true).await.unwrap();
646
647        let enabled = provider.anvil_get_auto_mine().await.unwrap();
648        assert!(enabled);
649    }
650
651    #[tokio::test]
652    async fn test_anvil_mine() {
653        let provider = ProviderBuilder::new().connect_anvil();
654
655        let start_num = provider.get_block_number().await.unwrap();
656
657        provider.anvil_mine(Some(10), None).await.unwrap();
658
659        let num = provider.get_block_number().await.unwrap();
660
661        assert_eq!(num, start_num + 10);
662    }
663
664    #[tokio::test]
665    async fn test_anvil_set_interval_mining() {
666        let provider = ProviderBuilder::new().connect_anvil();
667
668        provider.anvil_set_interval_mining(1).await.unwrap();
669
670        let start_num = provider.get_block_number().await.unwrap();
671
672        tokio::time::sleep(tokio::time::Duration::from_millis(1500)).await;
673
674        let num = provider.get_block_number().await.unwrap();
675
676        assert_eq!(num, start_num + 1);
677    }
678
679    #[tokio::test]
680    async fn test_anvil_drop_transaction() {
681        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
682
683        provider.anvil_set_auto_mine(false).await.unwrap();
684
685        let alice = provider.get_accounts().await.unwrap()[0];
686        let bob = provider.get_accounts().await.unwrap()[1];
687        let chain_id = provider.get_chain_id().await.unwrap();
688
689        let tx = TransactionRequest::default()
690            .with_from(alice)
691            .with_to(bob)
692            .with_nonce(0)
693            .with_chain_id(chain_id)
694            .with_value(U256::from(100))
695            .with_gas_limit(21_000)
696            .with_max_priority_fee_per_gas(1_000_000_000)
697            .with_max_fee_per_gas(20_000_000_000);
698
699        let tx_hash =
700            provider.send_transaction(tx).await.unwrap().register().await.unwrap().tx_hash;
701
702        let res = provider.anvil_drop_transaction(tx_hash).await.unwrap();
703
704        assert_eq!(res, Some(tx_hash));
705    }
706
707    #[tokio::test]
708    async fn test_anvil_drop_all_transactions() {
709        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
710
711        provider.anvil_set_auto_mine(false).await.unwrap();
712
713        let alice = provider.get_accounts().await.unwrap()[0];
714        let bob = provider.get_accounts().await.unwrap()[1];
715        let chain_id = provider.get_chain_id().await.unwrap();
716
717        let tx = TransactionRequest::default()
718            .with_from(alice)
719            .with_to(bob)
720            .with_nonce(0)
721            .with_chain_id(chain_id)
722            .with_value(U256::from(100))
723            .with_gas_limit(21_000)
724            .with_max_priority_fee_per_gas(1_000_000_000)
725            .with_max_fee_per_gas(20_000_000_000);
726
727        provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
728
729        let tx = tx.clone().with_nonce(1);
730
731        provider.send_transaction(tx).await.unwrap().register().await.unwrap();
732
733        provider.anvil_drop_all_transactions().await.unwrap();
734    }
735
736    // TODO: Fix this test, `chain_id` is not being set correctly.
737    // #[tokio::test]
738    // async fn test_anvil_reset() {
739    //     let fork1 = Anvil::default().chain_id(777).spawn();
740    //     let fork2 = Anvil::default().chain_id(888).spawn();
741
742    //     let provider = ProviderBuilder::new()
743    //         .connect_anvil_with_config(|config| config.fork(fork1.endpoint_url().to_string()));
744
745    //     let chain_id = provider.get_chain_id().await.unwrap();
746    //     assert_eq!(chain_id, 777);
747
748    //     provider
749    //         .anvil_reset(Some(Forking {
750    //             json_rpc_url: Some(fork2.endpoint_url().to_string()),
751    //             block_number: Some(0),
752    //         }))
753    //         .await
754    //         .unwrap();
755
756    //     let chain_id = provider.get_chain_id().await.unwrap();
757    //     assert_eq!(chain_id, 888);
758    // }
759
760    #[tokio::test]
761    async fn test_anvil_set_chain_id() {
762        let provider = ProviderBuilder::new().connect_anvil();
763
764        let chain_id = 1337;
765        provider.anvil_set_chain_id(chain_id).await.unwrap();
766
767        let new_chain_id = provider.get_chain_id().await.unwrap();
768        assert_eq!(new_chain_id, chain_id);
769    }
770
771    #[tokio::test]
772    async fn test_anvil_set_balance() {
773        let provider = ProviderBuilder::new().connect_anvil();
774
775        let address = Address::random();
776        let balance = U256::from(1337);
777        provider.anvil_set_balance(address, balance).await.unwrap();
778
779        let new_balance = provider.get_balance(address).await.unwrap();
780        assert_eq!(new_balance, balance);
781    }
782
783    #[tokio::test]
784    async fn test_anvil_set_code() {
785        let provider = ProviderBuilder::new().connect_anvil();
786
787        let address = Address::random();
788        provider.anvil_set_code(address, Bytes::from("0xbeef")).await.unwrap();
789
790        let code = provider.get_code_at(address).await.unwrap();
791        assert_eq!(code, Bytes::from("0xbeef"));
792    }
793
794    #[tokio::test]
795    async fn test_anvil_set_nonce() {
796        let provider = ProviderBuilder::new().connect_anvil();
797
798        let address = Address::random();
799        let nonce = 1337;
800        provider.anvil_set_nonce(address, nonce).await.unwrap();
801
802        let new_nonce = provider.get_transaction_count(address).await.unwrap();
803        assert_eq!(new_nonce, nonce);
804    }
805
806    #[tokio::test]
807    async fn test_anvil_set_storage_at() {
808        let provider = ProviderBuilder::new().connect_anvil();
809
810        let address = Address::random();
811        let slot = U256::from(1337);
812        let val = B256::from(U256::from(1337));
813        provider.anvil_set_storage_at(address, slot, val).await.unwrap();
814
815        let storage = provider.get_storage_at(address, slot).await.unwrap();
816        assert_eq!(B256::from(storage), val);
817    }
818
819    #[tokio::test]
820    async fn test_anvil_set_logging() {
821        let provider = ProviderBuilder::new().connect_anvil();
822
823        provider.anvil_set_logging(true).await.unwrap();
824    }
825
826    #[tokio::test]
827    async fn test_anvil_set_min_gas_price() {
828        let provider = ProviderBuilder::new().connect_anvil();
829
830        let gas = U256::from(1337);
831
832        if let Err(e) = provider.anvil_set_min_gas_price(gas.try_into().unwrap()).await {
833            assert_eq!(
834                e.to_string(),
835                "server returned an error response: error code -32602: anvil_setMinGasPrice is not supported when EIP-1559 is active"
836            );
837        }
838    }
839
840    #[tokio::test]
841    async fn test_anvil_set_next_block_base_fee_per_gas() {
842        let provider = ProviderBuilder::new().connect_anvil();
843
844        let basefee = 1337;
845        provider.anvil_set_next_block_base_fee_per_gas(basefee).await.unwrap();
846
847        provider.evm_mine(None).await.unwrap();
848
849        let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
850
851        assert_eq!(block.header.base_fee_per_gas, Some(basefee as u64));
852    }
853
854    #[tokio::test]
855    async fn test_anvil_set_coinbase() {
856        let provider = ProviderBuilder::new().connect_anvil();
857
858        let coinbase = Address::random();
859        provider.anvil_set_coinbase(coinbase).await.unwrap();
860
861        provider.evm_mine(None).await.unwrap();
862
863        let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
864        assert_eq!(block.header.beneficiary, coinbase);
865    }
866
867    #[tokio::test]
868    async fn test_anvil_dump_state_load_state() {
869        let provider = ProviderBuilder::new().connect_anvil();
870
871        let state = provider.anvil_dump_state().await.unwrap();
872
873        assert!(!state.is_empty());
874
875        let res = provider.anvil_load_state(state).await.unwrap();
876
877        assert!(res);
878    }
879
880    #[tokio::test]
881    async fn test_anvil_node_info() {
882        let provider = ProviderBuilder::new().connect_anvil();
883
884        let latest_block =
885            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
886
887        provider.evm_mine(None).await.unwrap();
888
889        let node_info = provider.anvil_node_info().await.unwrap();
890
891        assert_eq!(node_info.current_block_number, latest_block.header.number + 1);
892    }
893
894    #[tokio::test]
895    async fn test_anvil_metadata() {
896        let provider = ProviderBuilder::new().connect_anvil();
897
898        let client_version = provider.get_client_version().await.unwrap();
899        let chain_id = provider.get_chain_id().await.unwrap();
900
901        let metadata = provider.anvil_metadata().await.unwrap();
902
903        assert_eq!(metadata.client_version, client_version);
904        assert_eq!(metadata.chain_id, chain_id);
905    }
906
907    #[tokio::test]
908    async fn test_anvil_remove_pool_transactions() {
909        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
910
911        provider.anvil_set_auto_mine(false).await.unwrap();
912
913        let alice = provider.get_accounts().await.unwrap()[0];
914        let bob = provider.get_accounts().await.unwrap()[1];
915        let chain_id = provider.get_chain_id().await.unwrap();
916
917        let tx = TransactionRequest::default()
918            .with_from(alice)
919            .with_to(bob)
920            .with_nonce(0)
921            .with_chain_id(chain_id)
922            .with_value(U256::from(100))
923            .with_gas_limit(21_000)
924            .with_max_priority_fee_per_gas(1_000_000_000)
925            .with_max_fee_per_gas(20_000_000_000);
926
927        provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
928
929        let tx = tx.clone().with_nonce(1);
930
931        provider.send_transaction(tx).await.unwrap().register().await.unwrap();
932
933        provider.anvil_remove_pool_transactions(alice).await.unwrap();
934    }
935
936    #[tokio::test]
937    async fn test_anvil_snapshot_revert() {
938        let provider = ProviderBuilder::new().connect_anvil();
939
940        let snapshot_id = provider.anvil_snapshot().await.unwrap();
941
942        let alice = provider.get_accounts().await.unwrap()[0];
943        let bob = provider.get_accounts().await.unwrap()[1];
944        let chain_id = provider.get_chain_id().await.unwrap();
945
946        let tx = TransactionRequest::default()
947            .with_from(alice)
948            .with_to(bob)
949            .with_nonce(0)
950            .with_chain_id(chain_id)
951            .with_value(U256::from(100))
952            .with_gas_limit(21_000)
953            .with_max_priority_fee_per_gas(1_000_000_000)
954            .with_max_fee_per_gas(20_000_000_000);
955
956        provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
957
958        let tx = tx.clone().with_nonce(1);
959
960        provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap();
961
962        let tx_count = provider.get_transaction_count(alice).await.unwrap();
963        assert_eq!(tx_count, 2);
964
965        let res = provider.anvil_revert(snapshot_id).await.unwrap();
966        assert!(res);
967
968        let tx_count = provider.get_transaction_count(alice).await.unwrap();
969        assert_eq!(tx_count, 0);
970    }
971
972    #[tokio::test]
973    async fn test_anvil_increase_time() {
974        let provider = ProviderBuilder::new().connect_anvil();
975
976        let timestamp = provider
977            .get_block_by_number(BlockNumberOrTag::Latest)
978            .await
979            .unwrap()
980            .unwrap()
981            .header
982            .timestamp;
983
984        let seconds = provider.anvil_increase_time(1337).await.unwrap();
985
986        assert_eq!(timestamp as i64 + seconds, timestamp as i64 + 1337_i64);
987    }
988
989    #[tokio::test]
990    async fn test_anvil_set_next_block_timestamp() {
991        let provider = ProviderBuilder::new().connect_anvil();
992
993        let timestamp = provider
994            .get_block_by_number(BlockNumberOrTag::Latest)
995            .await
996            .unwrap()
997            .unwrap()
998            .header
999            .timestamp;
1000
1001        provider.anvil_set_next_block_timestamp(timestamp + 1337).await.unwrap();
1002
1003        provider.evm_mine(None).await.unwrap();
1004
1005        let latest_block =
1006            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1007        assert_eq!(latest_block.header.timestamp, timestamp + 1337);
1008    }
1009
1010    #[tokio::test]
1011    async fn test_anvil_set_time() {
1012        let provider = ProviderBuilder::new().connect_anvil();
1013
1014        provider.anvil_set_time(0).await.unwrap();
1015
1016        let seconds = provider.anvil_set_time(1001).await.unwrap();
1017
1018        assert_eq!(seconds, 1);
1019    }
1020
1021    #[tokio::test]
1022    async fn test_anvil_set_block_gas_limit() {
1023        let provider = ProviderBuilder::new().connect_anvil();
1024
1025        let block_gas_limit = 1337;
1026        assert!(provider.anvil_set_block_gas_limit(block_gas_limit).await.unwrap());
1027
1028        provider.evm_mine(None).await.unwrap();
1029
1030        let latest_block =
1031            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1032        assert_eq!(block_gas_limit, latest_block.header.gas_limit);
1033    }
1034
1035    #[tokio::test]
1036    async fn test_anvil_block_timestamp_interval() {
1037        let provider = ProviderBuilder::new().connect_anvil();
1038
1039        provider.anvil_set_block_timestamp_interval(1).await.unwrap();
1040
1041        let start_timestamp = provider
1042            .get_block_by_number(BlockNumberOrTag::Latest)
1043            .await
1044            .unwrap()
1045            .unwrap()
1046            .header
1047            .timestamp;
1048
1049        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1050
1051        provider.evm_mine(None).await.unwrap();
1052
1053        let latest_block =
1054            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1055
1056        assert_eq!(latest_block.header.timestamp, start_timestamp + 1);
1057
1058        provider.anvil_remove_block_timestamp_interval().await.unwrap();
1059
1060        provider.evm_mine(None).await.unwrap();
1061
1062        let start_timestamp = provider
1063            .get_block_by_number(BlockNumberOrTag::Latest)
1064            .await
1065            .unwrap()
1066            .unwrap()
1067            .header
1068            .timestamp;
1069
1070        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1071
1072        let latest_block =
1073            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1074
1075        assert_eq!(latest_block.header.timestamp, start_timestamp);
1076    }
1077
1078    #[tokio::test]
1079    async fn test_evm_mine_single_block() {
1080        let provider = ProviderBuilder::new().connect_anvil();
1081
1082        let start_num = provider.get_block_number().await.unwrap();
1083
1084        for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1085            provider.evm_mine(None).await.unwrap();
1086            let num = provider.get_block_number().await.unwrap();
1087            assert_eq!(num, start_num + idx as u64 + 1);
1088        }
1089
1090        let num = provider.get_block_number().await.unwrap();
1091        assert_eq!(num, start_num + 10);
1092    }
1093
1094    // TODO: Fix this test, only a single block is being mined regardless of the `blocks` parameter.
1095    // #[tokio::test]
1096    // async fn test_evm_mine_with_configuration() {
1097    //     let provider = ProviderBuilder::new().connect_anvil();
1098
1099    //     let start_num = provider.get_block_number().await.unwrap();
1100
1101    //     provider
1102    //         .evm_mine(Some(MineOptions::Options { timestamp: Some(100), blocks: Some(10) }))
1103    //         .await
1104    //         .unwrap();
1105
1106    //     let num = provider.get_block_number().await.unwrap();
1107    //     assert_eq!(num, start_num + 10);
1108    // }
1109
1110    #[tokio::test]
1111    async fn test_anvil_mine_detailed_single_block() {
1112        let provider = ProviderBuilder::new().connect_anvil();
1113
1114        let start_num = provider.get_block_number().await.unwrap();
1115
1116        for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1117            provider.anvil_mine_detailed(None).await.unwrap();
1118            let num = provider.get_block_number().await.unwrap();
1119            assert_eq!(num, start_num + idx as u64 + 1);
1120        }
1121
1122        let num = provider.get_block_number().await.unwrap();
1123        assert_eq!(num, start_num + 10);
1124    }
1125
1126    // TODO: Fix this test, only a single block is being mined regardless of the `blocks` parameter.
1127    // #[tokio::test]
1128    // async fn test_anvil_mine_detailed_with_configuration() {
1129    //     let provider = ProviderBuilder::new().connect_anvil();
1130
1131    //     let start_num = provider.get_block_number().await.unwrap();
1132
1133    //     let blocks = provider
1134    //         .anvil_mine_detailed(Some(MineOptions::Options {
1135    //             timestamp: Some(100),
1136    //             blocks: Some(10),
1137    //         }))
1138    //         .await
1139    //         .unwrap();
1140
1141    //     let num = provider.get_block_number().await.unwrap();
1142    //     assert_eq!(num, start_num + 10);
1143
1144    //     for (idx, block) in blocks.iter().enumerate() {
1145    //         assert_eq!(block.header.number, Some(start_num + idx as u64 + 1));
1146    //     }
1147    // }
1148
1149    #[tokio::test]
1150    async fn test_anvil_set_rpc_url() {
1151        let provider = ProviderBuilder::new().connect_anvil();
1152
1153        let url = "https://example.com".to_string();
1154        provider.anvil_set_rpc_url(url.clone()).await.unwrap();
1155    }
1156
1157    #[tokio::test]
1158    async fn test_anvil_reorg() {
1159        let provider = ProviderBuilder::new().connect_anvil();
1160
1161        // Mine two blocks
1162        provider.anvil_mine(Some(2), None).await.unwrap();
1163
1164        let reorged_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1165        provider.anvil_reorg(ReorgOptions { depth: 1, tx_block_pairs: Vec::new() }).await.unwrap();
1166
1167        let new_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1168
1169        assert_eq!(reorged_block.header.number, new_block.header.number);
1170        assert_ne!(reorged_block.header.hash, new_block.header.hash);
1171    }
1172
1173    #[tokio::test]
1174    #[ignore]
1175    async fn test_anvil_rollback() {
1176        let provider = ProviderBuilder::new().connect_anvil();
1177
1178        // Mine two blocks
1179        provider.anvil_mine(Some(2), None).await.unwrap();
1180
1181        let target_height = provider.get_block_by_number(1.into()).await.unwrap().unwrap();
1182
1183        provider.anvil_rollback(Some(1)).await.unwrap();
1184
1185        let new_head =
1186            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1187
1188        assert_eq!(target_height, new_head);
1189    }
1190
1191    #[tokio::test]
1192    async fn test_eth_send_unsigned_transaction() {
1193        let provider = ProviderBuilder::new().connect_anvil();
1194
1195        let alice = Address::random();
1196        let bob = Address::random();
1197        let chain_id = provider.get_chain_id().await.unwrap();
1198
1199        provider.anvil_set_balance(alice, U256::from(1e18 as u64)).await.unwrap();
1200
1201        let tx = TransactionRequest::default()
1202            .with_from(alice)
1203            .with_to(bob)
1204            .with_nonce(0)
1205            .with_chain_id(chain_id)
1206            .with_value(U256::from(100))
1207            .with_gas_limit(21_000)
1208            .with_max_priority_fee_per_gas(1_000_000_000)
1209            .with_max_fee_per_gas(20_000_000_000);
1210
1211        let tx_hash = provider.eth_send_unsigned_transaction(tx).await.unwrap();
1212
1213        provider.evm_mine(None).await.unwrap();
1214
1215        let res = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap();
1216        assert_eq!(res.from, alice);
1217        assert_eq!(res.to, Some(bob));
1218    }
1219
1220    #[tokio::test]
1221    async fn test_anvil_get_blob_by_versioned_hash() {
1222        std::thread::Builder::new()
1223            .stack_size(16 * 1024 * 1024)
1224            .spawn(|| {
1225                let rt = tokio::runtime::Runtime::new().unwrap();
1226                rt.block_on(async {
1227                    let provider = ProviderBuilder::new()
1228                        .connect_anvil_with_wallet_and_config(|anvil| {
1229                            anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1230                        })
1231                        .unwrap();
1232
1233                    let accounts = provider.get_accounts().await.unwrap();
1234                    let alice = accounts[0];
1235                    let bob = accounts[1];
1236                    let sidecar: SidecarBuilder<SimpleCoder> =
1237                        SidecarBuilder::from_slice(b"Blobs are fun!");
1238                    let sidecar = sidecar.build().unwrap();
1239
1240                    let tx = TransactionRequest::default()
1241                        .with_from(alice)
1242                        .with_to(bob)
1243                        .with_blob_sidecar(sidecar.clone());
1244
1245                    let pending_tx = provider.send_transaction(tx).await.unwrap();
1246                    let _receipt = pending_tx.get_receipt().await.unwrap();
1247                    let hash = sidecar.versioned_hash_for_blob(0).unwrap();
1248
1249                    let blob =
1250                        provider.anvil_get_blob_by_versioned_hash(hash).await.unwrap().unwrap();
1251
1252                    assert_eq!(blob, sidecar.blobs[0]);
1253                });
1254            })
1255            .unwrap()
1256            .join()
1257            .unwrap();
1258    }
1259
1260    #[tokio::test]
1261    async fn test_anvil_get_blobs_by_tx_hash() {
1262        std::thread::Builder::new()
1263            .stack_size(16 * 1024 * 1024)
1264            .spawn(|| {
1265                let rt = tokio::runtime::Runtime::new().unwrap();
1266                rt.block_on(async {
1267                    let provider = ProviderBuilder::new()
1268                        .connect_anvil_with_wallet_and_config(|anvil| {
1269                            anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1270                        })
1271                        .unwrap();
1272
1273                    let accounts = provider.get_accounts().await.unwrap();
1274                    let alice = accounts[0];
1275                    let bob = accounts[1];
1276                    let sidecar: SidecarBuilder<SimpleCoder> =
1277                        SidecarBuilder::from_slice(b"Blobs are fun!");
1278                    let sidecar = sidecar.build().unwrap();
1279
1280                    let tx = TransactionRequest::default()
1281                        .with_from(alice)
1282                        .with_to(bob)
1283                        .with_blob_sidecar(sidecar.clone());
1284
1285                    let pending_tx = provider.send_transaction(tx).await.unwrap();
1286                    let receipt = pending_tx.get_receipt().await.unwrap();
1287                    let tx_hash = receipt.transaction_hash;
1288
1289                    let blobs =
1290                        provider.anvil_get_blobs_by_tx_hash(tx_hash).await.unwrap().unwrap();
1291
1292                    assert_eq!(blobs, sidecar.blobs);
1293                });
1294            })
1295            .unwrap()
1296            .join()
1297            .unwrap();
1298    }
1299
1300    #[tokio::test]
1301    async fn test_anvil_deal_erc20() {
1302        let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1303
1304        let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1305        let user = Address::random();
1306        let amount = U256::from(1e18 as u64);
1307
1308        provider.anvil_deal_erc20(user, dai, amount).await.unwrap();
1309
1310        sol! {
1311            function balanceOf(address owner) view returns (uint256);
1312        }
1313
1314        let balance_of_call = balanceOfCall::new((user,));
1315        let input = balanceOfCall::abi_encode(&balance_of_call);
1316
1317        let result = provider
1318            .call(TransactionRequest::default().with_to(dai).with_input(input))
1319            .await
1320            .unwrap();
1321        let balance = balanceOfCall::abi_decode_returns(&result).unwrap();
1322
1323        assert_eq!(balance, amount);
1324    }
1325
1326    #[tokio::test]
1327    async fn test_anvil_set_erc20_allowance() {
1328        let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1329
1330        let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1331        let owner = Address::random();
1332        let spender = Address::random();
1333        let amount = U256::from(1e18 as u64);
1334
1335        provider.anvil_set_erc20_allowance(owner, spender, dai, amount).await.unwrap();
1336
1337        sol! {
1338            function allowance(address owner, address spender) view returns (uint256);
1339        }
1340
1341        let allowance_call = allowanceCall::new((owner, spender));
1342        let input = allowanceCall::abi_encode(&allowance_call);
1343
1344        let result = provider
1345            .call(TransactionRequest::default().with_to(dai).with_input(input))
1346            .await
1347            .unwrap();
1348        let allowance = allowanceCall::abi_decode_returns(&result).unwrap();
1349
1350        assert_eq!(allowance, amount);
1351    }
1352}