Skip to main content

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`, impersonates all accounts.
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    const FORK_URL: &str = "https://ethereum.reth.rs/rpc";
521
522    #[tokio::test]
523    async fn test_anvil_impersonate_account_stop_impersonating_account() {
524        let provider = ProviderBuilder::new()
525            .disable_recommended_fillers()
526            .with_simple_nonce_management()
527            .filler(GasFiller::default())
528            .filler(ChainIdFiller::default())
529            .connect_anvil();
530
531        let impersonate = Address::random();
532        let to = Address::random();
533        let val = U256::from(1337);
534        let funding = U256::from(1e18 as u64);
535
536        provider.anvil_set_balance(impersonate, funding).await.unwrap();
537
538        let balance = provider.get_balance(impersonate).await.unwrap();
539        assert_eq!(balance, funding);
540
541        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
542
543        let res = provider.send_transaction(tx.clone()).await;
544        res.unwrap_err();
545
546        provider.anvil_impersonate_account(impersonate).await.unwrap();
547        assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
548
549        let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
550        assert_eq!(res.from, impersonate);
551
552        let nonce = provider.get_transaction_count(impersonate).await.unwrap();
553        assert_eq!(nonce, 1);
554
555        let balance = provider.get_balance(to).await.unwrap();
556        assert_eq!(balance, val);
557
558        provider.anvil_stop_impersonating_account(impersonate).await.unwrap();
559        let res = provider.send_transaction(tx).await;
560        res.unwrap_err();
561    }
562
563    #[tokio::test]
564    async fn test_anvil_impersonated_send_with_config() {
565        let provider = ProviderBuilder::new()
566            .disable_recommended_fillers()
567            .with_simple_nonce_management()
568            .filler(GasFiller::default())
569            .filler(ChainIdFiller::default())
570            .connect_anvil();
571
572        let impersonate = Address::random();
573        let to = Address::random();
574        let val = U256::from(1337);
575        let funding = U256::from(1e18 as u64);
576
577        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
578
579        let config = ImpersonateConfig { fund_amount: Some(funding), stop_impersonate: true };
580
581        let pending = provider
582            .anvil_send_impersonated_transaction_with_config(tx.clone(), config)
583            .await
584            .expect("impersonated send failed");
585        let receipt = pending.get_receipt().await.unwrap();
586        assert_eq!(receipt.from, impersonate);
587
588        let recipient_balance = provider.get_balance(to).await.unwrap();
589        assert_eq!(recipient_balance, val);
590    }
591
592    #[tokio::test]
593    async fn test_anvil_auto_impersonate_account() {
594        let provider = ProviderBuilder::new()
595            .disable_recommended_fillers()
596            .with_simple_nonce_management()
597            .filler(GasFiller::default())
598            .filler(ChainIdFiller::default())
599            .connect_anvil();
600
601        let impersonate = Address::random();
602        let to = Address::random();
603        let val = U256::from(1337);
604        let funding = U256::from(1e18 as u64);
605
606        provider.anvil_set_balance(impersonate, funding).await.unwrap();
607
608        let balance = provider.get_balance(impersonate).await.unwrap();
609        assert_eq!(balance, funding);
610
611        let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
612
613        let res = provider.send_transaction(tx.clone()).await;
614        res.unwrap_err();
615
616        provider.anvil_auto_impersonate_account(true).await.unwrap();
617
618        let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
619        assert_eq!(res.from, impersonate);
620
621        let nonce = provider.get_transaction_count(impersonate).await.unwrap();
622        assert_eq!(nonce, 1);
623
624        let balance = provider.get_balance(to).await.unwrap();
625        assert_eq!(balance, val);
626
627        provider.anvil_auto_impersonate_account(false).await.unwrap();
628        let res = provider.send_transaction(tx).await;
629        res.unwrap_err();
630
631        provider.anvil_impersonate_account(impersonate).await.unwrap();
632        assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
633    }
634
635    #[tokio::test]
636    async fn test_anvil_get_auto_mine_set_auto_mine() {
637        let provider = ProviderBuilder::new().connect_anvil();
638
639        provider.anvil_set_auto_mine(false).await.unwrap();
640
641        let enabled = provider.anvil_get_auto_mine().await.unwrap();
642        assert!(!enabled);
643
644        provider.anvil_set_auto_mine(true).await.unwrap();
645
646        let enabled = provider.anvil_get_auto_mine().await.unwrap();
647        assert!(enabled);
648    }
649
650    #[tokio::test]
651    async fn test_anvil_mine() {
652        let provider = ProviderBuilder::new().connect_anvil();
653
654        let start_num = provider.get_block_number().await.unwrap();
655
656        provider.anvil_mine(Some(10), None).await.unwrap();
657
658        let num = provider.get_block_number().await.unwrap();
659
660        assert_eq!(num, start_num + 10);
661    }
662
663    #[tokio::test]
664    async fn test_anvil_set_interval_mining() {
665        let provider = ProviderBuilder::new().connect_anvil();
666
667        provider.anvil_set_interval_mining(1).await.unwrap();
668
669        let start_num = provider.get_block_number().await.unwrap();
670
671        tokio::time::sleep(tokio::time::Duration::from_millis(1500)).await;
672
673        let num = provider.get_block_number().await.unwrap();
674
675        assert_eq!(num, start_num + 1);
676    }
677
678    #[tokio::test]
679    async fn test_anvil_drop_transaction() {
680        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
681
682        provider.anvil_set_auto_mine(false).await.unwrap();
683
684        let alice = provider.get_accounts().await.unwrap()[0];
685        let bob = provider.get_accounts().await.unwrap()[1];
686        let chain_id = provider.get_chain_id().await.unwrap();
687
688        let tx = TransactionRequest::default()
689            .with_from(alice)
690            .with_to(bob)
691            .with_nonce(0)
692            .with_chain_id(chain_id)
693            .with_value(U256::from(100))
694            .with_gas_limit(21_000)
695            .with_max_priority_fee_per_gas(1_000_000_000)
696            .with_max_fee_per_gas(20_000_000_000);
697
698        let tx_hash =
699            provider.send_transaction(tx).await.unwrap().register().await.unwrap().tx_hash;
700
701        let res = provider.anvil_drop_transaction(tx_hash).await.unwrap();
702
703        assert_eq!(res, Some(tx_hash));
704    }
705
706    #[tokio::test]
707    async fn test_anvil_drop_all_transactions() {
708        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
709
710        provider.anvil_set_auto_mine(false).await.unwrap();
711
712        let alice = provider.get_accounts().await.unwrap()[0];
713        let bob = provider.get_accounts().await.unwrap()[1];
714        let chain_id = provider.get_chain_id().await.unwrap();
715
716        let tx = TransactionRequest::default()
717            .with_from(alice)
718            .with_to(bob)
719            .with_nonce(0)
720            .with_chain_id(chain_id)
721            .with_value(U256::from(100))
722            .with_gas_limit(21_000)
723            .with_max_priority_fee_per_gas(1_000_000_000)
724            .with_max_fee_per_gas(20_000_000_000);
725
726        provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
727
728        let tx = tx.clone().with_nonce(1);
729
730        provider.send_transaction(tx).await.unwrap().register().await.unwrap();
731
732        provider.anvil_drop_all_transactions().await.unwrap();
733    }
734
735    #[tokio::test]
736    async fn test_anvil_reset() {
737        let provider = ProviderBuilder::new().connect_anvil();
738
739        let alice = Address::random();
740        let balance = U256::from(1e18 as u64);
741        provider.anvil_set_balance(alice, balance).await.unwrap();
742
743        let current_balance = provider.get_balance(alice).await.unwrap();
744        assert_eq!(current_balance, balance);
745
746        provider.anvil_reset(None).await.unwrap();
747
748        let reset_balance = provider.get_balance(alice).await.unwrap();
749        assert_eq!(reset_balance, U256::ZERO);
750    }
751
752    #[tokio::test]
753    async fn test_anvil_set_chain_id() {
754        let provider = ProviderBuilder::new().connect_anvil();
755
756        let chain_id = 1337;
757        provider.anvil_set_chain_id(chain_id).await.unwrap();
758
759        let new_chain_id = provider.get_chain_id().await.unwrap();
760        assert_eq!(new_chain_id, chain_id);
761    }
762
763    #[tokio::test]
764    async fn test_anvil_set_balance() {
765        let provider = ProviderBuilder::new().connect_anvil();
766
767        let address = Address::random();
768        let balance = U256::from(1337);
769        provider.anvil_set_balance(address, balance).await.unwrap();
770
771        let new_balance = provider.get_balance(address).await.unwrap();
772        assert_eq!(new_balance, balance);
773    }
774
775    #[tokio::test]
776    async fn test_anvil_set_code() {
777        let provider = ProviderBuilder::new().connect_anvil();
778
779        let address = Address::random();
780        provider.anvil_set_code(address, Bytes::from("0xbeef")).await.unwrap();
781
782        let code = provider.get_code_at(address).await.unwrap();
783        assert_eq!(code, Bytes::from("0xbeef"));
784    }
785
786    #[tokio::test]
787    async fn test_anvil_set_nonce() {
788        let provider = ProviderBuilder::new().connect_anvil();
789
790        let address = Address::random();
791        let nonce = 1337;
792        provider.anvil_set_nonce(address, nonce).await.unwrap();
793
794        let new_nonce = provider.get_transaction_count(address).await.unwrap();
795        assert_eq!(new_nonce, nonce);
796    }
797
798    #[tokio::test]
799    async fn test_anvil_set_storage_at() {
800        let provider = ProviderBuilder::new().connect_anvil();
801
802        let address = Address::random();
803        let slot = U256::from(1337);
804        let val = B256::from(U256::from(1337));
805        provider.anvil_set_storage_at(address, slot, val).await.unwrap();
806
807        let storage = provider.get_storage_at(address, slot).await.unwrap();
808        assert_eq!(B256::from(storage), val);
809    }
810
811    #[tokio::test]
812    async fn test_anvil_set_logging() {
813        let provider = ProviderBuilder::new().connect_anvil();
814
815        provider.anvil_set_logging(true).await.unwrap();
816    }
817
818    #[tokio::test]
819    async fn test_anvil_set_min_gas_price() {
820        let provider = ProviderBuilder::new().connect_anvil();
821
822        let gas = U256::from(1337);
823
824        if let Err(e) = provider.anvil_set_min_gas_price(gas.try_into().unwrap()).await {
825            assert_eq!(
826                e.to_string(),
827                "server returned an error response: error code -32602: anvil_setMinGasPrice is not supported when EIP-1559 is active"
828            );
829        }
830    }
831
832    #[tokio::test]
833    async fn test_anvil_set_next_block_base_fee_per_gas() {
834        let provider = ProviderBuilder::new().connect_anvil();
835
836        let basefee = 1337;
837        provider.anvil_set_next_block_base_fee_per_gas(basefee).await.unwrap();
838
839        provider.evm_mine(None).await.unwrap();
840
841        let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
842
843        assert_eq!(block.header.base_fee_per_gas, Some(basefee as u64));
844    }
845
846    #[tokio::test]
847    async fn test_anvil_set_coinbase() {
848        let provider = ProviderBuilder::new().connect_anvil();
849
850        let coinbase = Address::random();
851        provider.anvil_set_coinbase(coinbase).await.unwrap();
852
853        provider.evm_mine(None).await.unwrap();
854
855        let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
856        assert_eq!(block.header.beneficiary, coinbase);
857    }
858
859    #[tokio::test]
860    async fn test_anvil_dump_state_load_state() {
861        let provider = ProviderBuilder::new().connect_anvil();
862
863        let state = provider.anvil_dump_state().await.unwrap();
864
865        assert!(!state.is_empty());
866
867        let res = provider.anvil_load_state(state).await.unwrap();
868
869        assert!(res);
870    }
871
872    #[tokio::test]
873    async fn test_anvil_node_info() {
874        let provider = ProviderBuilder::new().connect_anvil();
875
876        let latest_block =
877            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
878
879        provider.evm_mine(None).await.unwrap();
880
881        let node_info = provider.anvil_node_info().await.unwrap();
882
883        assert_eq!(node_info.current_block_number, latest_block.header.number + 1);
884    }
885
886    #[tokio::test]
887    async fn test_anvil_metadata() {
888        let provider = ProviderBuilder::new().connect_anvil();
889
890        let client_version = provider.get_client_version().await.unwrap();
891        let chain_id = provider.get_chain_id().await.unwrap();
892
893        let metadata = provider.anvil_metadata().await.unwrap();
894
895        assert_eq!(metadata.client_version, client_version);
896        assert_eq!(metadata.chain_id, chain_id);
897    }
898
899    #[tokio::test]
900    async fn test_anvil_remove_pool_transactions() {
901        let provider = ProviderBuilder::new().connect_anvil_with_wallet();
902
903        provider.anvil_set_auto_mine(false).await.unwrap();
904
905        let alice = provider.get_accounts().await.unwrap()[0];
906        let bob = provider.get_accounts().await.unwrap()[1];
907        let chain_id = provider.get_chain_id().await.unwrap();
908
909        let tx = TransactionRequest::default()
910            .with_from(alice)
911            .with_to(bob)
912            .with_nonce(0)
913            .with_chain_id(chain_id)
914            .with_value(U256::from(100))
915            .with_gas_limit(21_000)
916            .with_max_priority_fee_per_gas(1_000_000_000)
917            .with_max_fee_per_gas(20_000_000_000);
918
919        provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
920
921        let tx = tx.clone().with_nonce(1);
922
923        provider.send_transaction(tx).await.unwrap().register().await.unwrap();
924
925        provider.anvil_remove_pool_transactions(alice).await.unwrap();
926    }
927
928    #[tokio::test]
929    async fn test_anvil_snapshot_revert() {
930        let provider = ProviderBuilder::new().connect_anvil();
931
932        let snapshot_id = provider.anvil_snapshot().await.unwrap();
933
934        let alice = provider.get_accounts().await.unwrap()[0];
935        let bob = provider.get_accounts().await.unwrap()[1];
936        let chain_id = provider.get_chain_id().await.unwrap();
937
938        let tx = TransactionRequest::default()
939            .with_from(alice)
940            .with_to(bob)
941            .with_nonce(0)
942            .with_chain_id(chain_id)
943            .with_value(U256::from(100))
944            .with_gas_limit(21_000)
945            .with_max_priority_fee_per_gas(1_000_000_000)
946            .with_max_fee_per_gas(20_000_000_000);
947
948        provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
949
950        let tx = tx.clone().with_nonce(1);
951
952        provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap();
953
954        let tx_count = provider.get_transaction_count(alice).await.unwrap();
955        assert_eq!(tx_count, 2);
956
957        let res = provider.anvil_revert(snapshot_id).await.unwrap();
958        assert!(res);
959
960        let tx_count = provider.get_transaction_count(alice).await.unwrap();
961        assert_eq!(tx_count, 0);
962    }
963
964    #[tokio::test]
965    async fn test_anvil_increase_time() {
966        let provider = ProviderBuilder::new().connect_anvil();
967
968        let timestamp = provider
969            .get_block_by_number(BlockNumberOrTag::Latest)
970            .await
971            .unwrap()
972            .unwrap()
973            .header
974            .timestamp;
975
976        let seconds = provider.anvil_increase_time(1337).await.unwrap();
977
978        assert_eq!(timestamp as i64 + seconds, timestamp as i64 + 1337_i64);
979    }
980
981    #[tokio::test]
982    async fn test_anvil_set_next_block_timestamp() {
983        let provider = ProviderBuilder::new().connect_anvil();
984
985        let timestamp = provider
986            .get_block_by_number(BlockNumberOrTag::Latest)
987            .await
988            .unwrap()
989            .unwrap()
990            .header
991            .timestamp;
992
993        provider.anvil_set_next_block_timestamp(timestamp + 1337).await.unwrap();
994
995        provider.evm_mine(None).await.unwrap();
996
997        let latest_block =
998            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
999        assert_eq!(latest_block.header.timestamp, timestamp + 1337);
1000    }
1001
1002    #[tokio::test]
1003    async fn test_anvil_set_time() {
1004        let provider = ProviderBuilder::new().connect_anvil();
1005
1006        provider.anvil_set_time(0).await.unwrap();
1007
1008        let seconds = provider.anvil_set_time(1001).await.unwrap();
1009
1010        assert_eq!(seconds, 1001);
1011    }
1012
1013    #[tokio::test]
1014    async fn test_anvil_set_block_gas_limit() {
1015        let provider = ProviderBuilder::new().connect_anvil();
1016
1017        let block_gas_limit = 1337;
1018        assert!(provider.anvil_set_block_gas_limit(block_gas_limit).await.unwrap());
1019
1020        provider.evm_mine(None).await.unwrap();
1021
1022        let latest_block =
1023            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1024        assert_eq!(block_gas_limit, latest_block.header.gas_limit);
1025    }
1026
1027    #[tokio::test]
1028    async fn test_anvil_block_timestamp_interval() {
1029        let provider = ProviderBuilder::new().connect_anvil();
1030
1031        provider.anvil_set_block_timestamp_interval(1).await.unwrap();
1032
1033        let start_timestamp = provider
1034            .get_block_by_number(BlockNumberOrTag::Latest)
1035            .await
1036            .unwrap()
1037            .unwrap()
1038            .header
1039            .timestamp;
1040
1041        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1042
1043        provider.evm_mine(None).await.unwrap();
1044
1045        let latest_block =
1046            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1047
1048        assert_eq!(latest_block.header.timestamp, start_timestamp + 1);
1049
1050        provider.anvil_remove_block_timestamp_interval().await.unwrap();
1051
1052        provider.evm_mine(None).await.unwrap();
1053
1054        let start_timestamp = provider
1055            .get_block_by_number(BlockNumberOrTag::Latest)
1056            .await
1057            .unwrap()
1058            .unwrap()
1059            .header
1060            .timestamp;
1061
1062        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1063
1064        let latest_block =
1065            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1066
1067        assert_eq!(latest_block.header.timestamp, start_timestamp);
1068    }
1069
1070    #[tokio::test]
1071    async fn test_evm_mine_single_block() {
1072        let provider = ProviderBuilder::new().connect_anvil();
1073
1074        let start_num = provider.get_block_number().await.unwrap();
1075
1076        for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1077            provider.evm_mine(None).await.unwrap();
1078            let num = provider.get_block_number().await.unwrap();
1079            assert_eq!(num, start_num + idx as u64 + 1);
1080        }
1081
1082        let num = provider.get_block_number().await.unwrap();
1083        assert_eq!(num, start_num + 10);
1084    }
1085
1086    #[tokio::test]
1087    async fn test_evm_mine_with_configuration() {
1088        let provider = ProviderBuilder::new().connect_anvil();
1089
1090        let start_num = provider.get_block_number().await.unwrap();
1091
1092        provider
1093            .evm_mine(Some(MineOptions::Options { timestamp: None, blocks: Some(10) }))
1094            .await
1095            .unwrap();
1096
1097        let num = provider.get_block_number().await.unwrap();
1098        assert_eq!(num, start_num + 10);
1099    }
1100
1101    #[tokio::test]
1102    async fn test_anvil_mine_detailed_single_block() {
1103        let provider = ProviderBuilder::new().connect_anvil();
1104
1105        let start_num = provider.get_block_number().await.unwrap();
1106
1107        for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1108            provider.anvil_mine_detailed(None).await.unwrap();
1109            let num = provider.get_block_number().await.unwrap();
1110            assert_eq!(num, start_num + idx as u64 + 1);
1111        }
1112
1113        let num = provider.get_block_number().await.unwrap();
1114        assert_eq!(num, start_num + 10);
1115    }
1116
1117    #[tokio::test]
1118    async fn test_anvil_mine_detailed_with_configuration() {
1119        let provider = ProviderBuilder::new().connect_anvil();
1120
1121        let start_num = provider.get_block_number().await.unwrap();
1122
1123        let blocks = provider
1124            .anvil_mine_detailed(Some(MineOptions::Options { timestamp: None, blocks: Some(10) }))
1125            .await
1126            .unwrap();
1127
1128        let num = provider.get_block_number().await.unwrap();
1129        assert_eq!(num, start_num + 10);
1130
1131        for (idx, block) in blocks.iter().enumerate() {
1132            assert_eq!(block.header.number, start_num + idx as u64 + 1);
1133        }
1134    }
1135
1136    #[tokio::test]
1137    async fn test_anvil_set_rpc_url() {
1138        let provider = ProviderBuilder::new().connect_anvil();
1139
1140        let url = "https://example.com".to_string();
1141        provider.anvil_set_rpc_url(url.clone()).await.unwrap();
1142    }
1143
1144    #[tokio::test]
1145    async fn test_anvil_reorg() {
1146        let provider = ProviderBuilder::new().connect_anvil();
1147
1148        // Mine two blocks
1149        provider.anvil_mine(Some(2), None).await.unwrap();
1150
1151        let reorged_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1152        provider.anvil_reorg(ReorgOptions { depth: 1, tx_block_pairs: Vec::new() }).await.unwrap();
1153
1154        let new_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1155
1156        assert_eq!(reorged_block.header.number, new_block.header.number);
1157        assert_ne!(reorged_block.header.hash, new_block.header.hash);
1158    }
1159
1160    #[tokio::test]
1161    #[ignore]
1162    async fn test_anvil_rollback() {
1163        let provider = ProviderBuilder::new().connect_anvil();
1164
1165        // Mine two blocks
1166        provider.anvil_mine(Some(2), None).await.unwrap();
1167
1168        let target_height = provider.get_block_by_number(1.into()).await.unwrap().unwrap();
1169
1170        provider.anvil_rollback(Some(1)).await.unwrap();
1171
1172        let new_head =
1173            provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1174
1175        assert_eq!(target_height, new_head);
1176    }
1177
1178    #[tokio::test]
1179    async fn test_eth_send_unsigned_transaction() {
1180        let provider = ProviderBuilder::new().connect_anvil();
1181
1182        let alice = Address::random();
1183        let bob = Address::random();
1184        let chain_id = provider.get_chain_id().await.unwrap();
1185
1186        provider.anvil_set_balance(alice, U256::from(1e18 as u64)).await.unwrap();
1187
1188        let tx = TransactionRequest::default()
1189            .with_from(alice)
1190            .with_to(bob)
1191            .with_nonce(0)
1192            .with_chain_id(chain_id)
1193            .with_value(U256::from(100))
1194            .with_gas_limit(21_000)
1195            .with_max_priority_fee_per_gas(1_000_000_000)
1196            .with_max_fee_per_gas(20_000_000_000);
1197
1198        let tx_hash = provider.eth_send_unsigned_transaction(tx).await.unwrap();
1199
1200        provider.evm_mine(None).await.unwrap();
1201
1202        let res = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap();
1203        assert_eq!(res.from, alice);
1204        assert_eq!(res.to, Some(bob));
1205    }
1206
1207    #[tokio::test]
1208    async fn test_anvil_get_blob_by_versioned_hash() {
1209        std::thread::Builder::new()
1210            .stack_size(16 * 1024 * 1024)
1211            .spawn(|| {
1212                let rt = tokio::runtime::Runtime::new().unwrap();
1213                rt.block_on(async {
1214                    let provider = ProviderBuilder::new()
1215                        .connect_anvil_with_wallet_and_config(|anvil| {
1216                            anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1217                        })
1218                        .unwrap();
1219
1220                    let accounts = provider.get_accounts().await.unwrap();
1221                    let alice = accounts[0];
1222                    let bob = accounts[1];
1223                    let sidecar: SidecarBuilder<SimpleCoder> =
1224                        SidecarBuilder::from_slice(b"Blobs are fun!");
1225                    let sidecar = sidecar.build_4844().unwrap();
1226
1227                    let tx = TransactionRequest::default()
1228                        .with_from(alice)
1229                        .with_to(bob)
1230                        .with_blob_sidecar_4844(sidecar.clone());
1231
1232                    let pending_tx = provider.send_transaction(tx).await.unwrap();
1233                    let _receipt = pending_tx.get_receipt().await.unwrap();
1234                    let hash = sidecar.versioned_hash_for_blob(0).unwrap();
1235
1236                    let blob =
1237                        provider.anvil_get_blob_by_versioned_hash(hash).await.unwrap().unwrap();
1238
1239                    assert_eq!(blob, sidecar.blobs[0]);
1240                });
1241            })
1242            .unwrap()
1243            .join()
1244            .unwrap();
1245    }
1246
1247    #[tokio::test]
1248    async fn test_anvil_get_blobs_by_tx_hash() {
1249        std::thread::Builder::new()
1250            .stack_size(16 * 1024 * 1024)
1251            .spawn(|| {
1252                let rt = tokio::runtime::Runtime::new().unwrap();
1253                rt.block_on(async {
1254                    let provider = ProviderBuilder::new()
1255                        .connect_anvil_with_wallet_and_config(|anvil| {
1256                            anvil.fork(FORK_URL).args(["--hardfork", "cancun"])
1257                        })
1258                        .unwrap();
1259
1260                    let accounts = provider.get_accounts().await.unwrap();
1261                    let alice = accounts[0];
1262                    let bob = accounts[1];
1263                    let sidecar: SidecarBuilder<SimpleCoder> =
1264                        SidecarBuilder::from_slice(b"Blobs are fun!");
1265                    let sidecar = sidecar.build_4844().unwrap();
1266
1267                    let tx = TransactionRequest::default()
1268                        .with_from(alice)
1269                        .with_to(bob)
1270                        .with_blob_sidecar_4844(sidecar.clone());
1271
1272                    let pending_tx = provider.send_transaction(tx).await.unwrap();
1273                    let receipt = pending_tx.get_receipt().await.unwrap();
1274                    let tx_hash = receipt.transaction_hash;
1275
1276                    let blobs =
1277                        provider.anvil_get_blobs_by_tx_hash(tx_hash).await.unwrap().unwrap();
1278
1279                    assert_eq!(blobs, sidecar.blobs);
1280                });
1281            })
1282            .unwrap()
1283            .join()
1284            .unwrap();
1285    }
1286
1287    #[tokio::test]
1288    async fn test_anvil_deal_erc20() {
1289        let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1290
1291        let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1292        let user = Address::random();
1293        let amount = U256::from(1e18 as u64);
1294
1295        provider.anvil_deal_erc20(user, dai, amount).await.unwrap();
1296
1297        sol! {
1298            function balanceOf(address owner) view returns (uint256);
1299        }
1300
1301        let balance_of_call = balanceOfCall::new((user,));
1302        let input = balanceOfCall::abi_encode(&balance_of_call);
1303
1304        let result = provider
1305            .call(TransactionRequest::default().with_to(dai).with_input(input))
1306            .await
1307            .unwrap();
1308        let balance = balanceOfCall::abi_decode_returns(&result).unwrap();
1309
1310        assert_eq!(balance, amount);
1311    }
1312
1313    #[tokio::test]
1314    async fn test_anvil_set_erc20_allowance() {
1315        let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1316
1317        let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1318        let owner = Address::random();
1319        let spender = Address::random();
1320        let amount = U256::from(1e18 as u64);
1321
1322        provider.anvil_set_erc20_allowance(owner, spender, dai, amount).await.unwrap();
1323
1324        sol! {
1325            function allowance(address owner, address spender) view returns (uint256);
1326        }
1327
1328        let allowance_call = allowanceCall::new((owner, spender));
1329        let input = allowanceCall::abi_encode(&allowance_call);
1330
1331        let result = provider
1332            .call(TransactionRequest::default().with_to(dai).with_input(input))
1333            .await
1334            .unwrap();
1335        let allowance = allowanceCall::abi_decode_returns(&result).unwrap();
1336
1337        assert_eq!(allowance, amount);
1338    }
1339}