1use crate::{PendingTransactionBuilder, Provider};
4use alloy_network::{Network, TransactionBuilder};
5use alloy_primitives::{Address, Bytes, TxHash, B256, U128, U256, U64};
6use alloy_rpc_types_anvil::{Forking, Metadata, MineOptions, NodeInfo, ReorgOptions};
7use alloy_rpc_types_eth::Block;
8use alloy_transport::{TransportError, TransportResult};
9use futures::try_join;
10
11#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
13#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
14pub trait AnvilApi<N: Network>: Send + Sync {
15 async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()>;
21
22 async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()>;
24
25 async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()>;
27
28 async fn anvil_send_impersonated_transaction_with_config(
32 &self,
33 request: N::TransactionRequest,
34 config: ImpersonateConfig,
35 ) -> TransportResult<PendingTransactionBuilder<N>>;
36
37 async fn anvil_get_auto_mine(&self) -> TransportResult<bool>;
39
40 async fn anvil_set_auto_mine(&self, enable_automine: bool) -> TransportResult<()>;
43
44 async fn anvil_mine(
46 &self,
47 num_blocks: Option<u64>,
48 interval: Option<u64>,
49 ) -> TransportResult<()>;
50
51 async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()>;
53
54 async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>>;
56
57 async fn anvil_drop_all_transactions(&self) -> TransportResult<()>;
59
60 async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()>;
64
65 async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()>;
67
68 async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()>;
70
71 async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()>;
73
74 async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()>;
76
77 async fn anvil_set_storage_at(
79 &self,
80 address: Address,
81 slot: U256,
82 val: B256,
83 ) -> TransportResult<bool>;
84
85 async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()>;
87
88 async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()>;
90
91 async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()>;
93
94 async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()>;
96
97 async fn anvil_dump_state(&self) -> TransportResult<Bytes>;
100
101 async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool>;
104
105 async fn anvil_node_info(&self) -> TransportResult<NodeInfo>;
107
108 async fn anvil_metadata(&self) -> TransportResult<Metadata>;
110
111 async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()>;
113
114 async fn anvil_snapshot(&self) -> TransportResult<U256>;
116
117 async fn anvil_revert(&self, id: U256) -> TransportResult<bool>;
120
121 async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64>;
123
124 async fn anvil_set_next_block_timestamp(&self, timestamp: u64) -> TransportResult<()>;
126
127 async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64>;
130
131 async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool>;
133
134 async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()>;
136
137 async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool>;
139
140 async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String>;
143
144 async fn anvil_mine_detailed(&self, opts: Option<MineOptions>) -> TransportResult<Vec<Block>>;
147
148 async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()>;
150
151 async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()>;
153
154 async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()>;
156
157 async fn eth_send_unsigned_transaction(
159 &self,
160 request: N::TransactionRequest,
161 ) -> TransportResult<TxHash>;
162
163 async fn eth_send_transaction_sync(
165 &self,
166 request: N::TransactionRequest,
167 ) -> TransportResult<N::ReceiptResponse>;
168
169 async fn eth_send_raw_transaction_sync(
171 &self,
172 request: Bytes,
173 ) -> TransportResult<N::ReceiptResponse>;
174
175 async fn anvil_send_impersonated_transaction(
177 &self,
178 request: N::TransactionRequest,
179 ) -> TransportResult<TxHash>;
180
181 async fn anvil_deal_erc20(
183 &self,
184 address: Address,
185 token_address: Address,
186 balance: U256,
187 ) -> TransportResult<()>;
188
189 async fn anvil_set_erc20_allowance(
191 &self,
192 owner: Address,
193 spender: Address,
194 token: Address,
195 allowance: U256,
196 ) -> TransportResult<()>;
197}
198
199#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
200#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
201impl<N, P> AnvilApi<N> for P
202where
203 N: Network,
204 P: Provider<N>,
205{
206 async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()> {
207 self.client().request("anvil_impersonateAccount", (address,)).await
208 }
209
210 async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()> {
211 self.client().request("anvil_stopImpersonatingAccount", (address,)).await
212 }
213
214 async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()> {
215 self.client().request("anvil_autoImpersonateAccount", (enabled,)).await
216 }
217
218 async fn anvil_get_auto_mine(&self) -> TransportResult<bool> {
219 self.client().request_noparams("anvil_getAutomine").await
220 }
221
222 async fn anvil_set_auto_mine(&self, enabled: bool) -> TransportResult<()> {
223 self.client().request("anvil_setAutomine", (enabled,)).await
224 }
225
226 async fn anvil_mine(
227 &self,
228 num_blocks: Option<u64>,
229 interval: Option<u64>,
230 ) -> TransportResult<()> {
231 self.client()
232 .request("anvil_mine", (num_blocks.map(U64::from), interval.map(U64::from)))
233 .await
234 }
235
236 async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()> {
237 self.client().request("anvil_setIntervalMining", (secs,)).await
238 }
239
240 async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>> {
241 self.client().request("anvil_dropTransaction", (tx_hash,)).await
242 }
243
244 async fn anvil_drop_all_transactions(&self) -> TransportResult<()> {
245 self.client().request_noparams("anvil_dropAllTransactions").await
246 }
247
248 async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()> {
249 self.client().request("anvil_reset", (forking,)).await
250 }
251
252 async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()> {
253 self.client().request("anvil_setChainId", (chain_id,)).await
254 }
255
256 async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()> {
257 self.client().request("anvil_setBalance", (address, balance)).await
258 }
259
260 async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()> {
261 self.client().request("anvil_setCode", (address, code)).await
262 }
263
264 async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()> {
265 self.client().request("anvil_setNonce", (address, U64::from(nonce))).await
266 }
267
268 async fn anvil_set_storage_at(
269 &self,
270 address: Address,
271 slot: U256,
272 val: B256,
273 ) -> TransportResult<bool> {
274 self.client().request("anvil_setStorageAt", (address, slot, val)).await
275 }
276
277 async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()> {
278 self.client().request("anvil_setLoggingEnabled", (enable,)).await
279 }
280
281 async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()> {
282 self.client().request("anvil_setMinGasPrice", (U128::from(gas),)).await
283 }
284
285 async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()> {
286 self.client().request("anvil_setNextBlockBaseFeePerGas", (U128::from(basefee),)).await
287 }
288
289 async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()> {
290 self.client().request("anvil_setCoinbase", (address,)).await
291 }
292
293 async fn anvil_dump_state(&self) -> TransportResult<Bytes> {
294 self.client().request_noparams("anvil_dumpState").await
295 }
296
297 async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool> {
298 self.client().request("anvil_loadState", (buf,)).await
299 }
300
301 async fn anvil_node_info(&self) -> TransportResult<NodeInfo> {
302 self.client().request_noparams("anvil_nodeInfo").await
303 }
304
305 async fn anvil_metadata(&self) -> TransportResult<Metadata> {
306 self.client().request_noparams("anvil_metadata").await
307 }
308
309 async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()> {
310 self.client().request("anvil_removePoolTransactions", (address,)).await
311 }
312
313 async fn anvil_snapshot(&self) -> TransportResult<U256> {
314 self.client().request_noparams("evm_snapshot").await
315 }
316
317 async fn anvil_revert(&self, id: U256) -> TransportResult<bool> {
318 self.client().request("evm_revert", (id,)).await
319 }
320
321 async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64> {
322 self.client().request("evm_increaseTime", (U64::from(seconds),)).await
323 }
324
325 async fn anvil_set_next_block_timestamp(&self, seconds: u64) -> TransportResult<()> {
326 self.client().request("evm_setNextBlockTimestamp", (seconds,)).await
327 }
328
329 async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64> {
330 self.client().request("evm_setTime", (timestamp,)).await
331 }
332
333 async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool> {
334 self.client().request("evm_setBlockGasLimit", (U64::from(gas_limit),)).await
335 }
336
337 async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()> {
338 self.client().request("anvil_setBlockTimestampInterval", (seconds,)).await
339 }
340
341 async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool> {
342 self.client().request_noparams("anvil_removeBlockTimestampInterval").await
343 }
344
345 async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String> {
346 self.client().request("evm_mine", (opts,)).await
347 }
348
349 async fn anvil_mine_detailed(&self, opts: Option<MineOptions>) -> TransportResult<Vec<Block>> {
350 self.client().request("evm_mine_detailed", (opts,)).await
351 }
352
353 async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()> {
354 self.client().request("anvil_setRpcUrl", (url,)).await
355 }
356
357 async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()> {
358 self.client().request("anvil_reorg", options).await
359 }
360
361 async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()> {
362 self.client().request("anvil_rollback", (depth,)).await
363 }
364
365 async fn eth_send_unsigned_transaction(
366 &self,
367 request: N::TransactionRequest,
368 ) -> TransportResult<TxHash> {
369 self.client().request("eth_sendUnsignedTransaction", (request,)).await
370 }
371
372 async fn eth_send_transaction_sync(
373 &self,
374 request: N::TransactionRequest,
375 ) -> TransportResult<N::ReceiptResponse> {
376 self.client().request("eth_sendTransactionSync", (request,)).await
377 }
378
379 async fn eth_send_raw_transaction_sync(
380 &self,
381 request: Bytes,
382 ) -> TransportResult<N::ReceiptResponse> {
383 self.client().request("eth_sendRawTransactionSync", (request,)).await
384 }
385
386 async fn anvil_send_impersonated_transaction(
387 &self,
388 request: N::TransactionRequest,
389 ) -> TransportResult<TxHash> {
390 self.client().request("eth_sendTransaction", (request,)).await
391 }
392
393 async fn anvil_deal_erc20(
394 &self,
395 address: Address,
396 token_address: Address,
397 balance: U256,
398 ) -> TransportResult<()> {
399 self.client().request("anvil_dealERC20", (address, token_address, balance)).await
400 }
401
402 async fn anvil_set_erc20_allowance(
403 &self,
404 owner: Address,
405 spender: Address,
406 token: Address,
407 allowance: U256,
408 ) -> TransportResult<()> {
409 self.client().request("anvil_setERC20Allowance", (owner, spender, token, allowance)).await
410 }
411
412 async fn anvil_send_impersonated_transaction_with_config(
413 &self,
414 request: N::TransactionRequest,
415 config: ImpersonateConfig,
416 ) -> TransportResult<PendingTransactionBuilder<N>> {
417 let from = request.from().ok_or_else(|| {
418 TransportError::from(alloy_transport::TransportErrorKind::Custom(
419 "TransactionRequest must have a `from` address set.".to_string().into(),
420 ))
421 })?;
422
423 let impersonate_future = self.anvil_impersonate_account(from);
424
425 if let Some(amount) = config.fund_amount {
426 let fund_future = self.anvil_set_balance(from, amount);
427 try_join!(fund_future, impersonate_future)?;
428 } else {
429 impersonate_future.await?;
430 }
431
432 let tx_hash = self.anvil_send_impersonated_transaction(request).await?;
433 let pending = PendingTransactionBuilder::new(self.root().clone(), tx_hash);
434
435 if config.stop_impersonate {
436 self.anvil_stop_impersonating_account(from).await?;
437 }
438
439 Ok(pending)
440 }
441}
442
443#[derive(Debug, Clone)]
446pub struct ImpersonateConfig {
447 pub fund_amount: Option<U256>,
449 pub stop_impersonate: bool,
451}
452
453impl Default for ImpersonateConfig {
454 fn default() -> Self {
455 Self { fund_amount: None, stop_impersonate: true }
456 }
457}
458
459impl ImpersonateConfig {
460 pub const fn keep_impersonate(mut self) -> Self {
462 self.stop_impersonate = false;
463 self
464 }
465
466 pub const fn stop_impersonate(mut self) -> Self {
468 self.stop_impersonate = true;
469 self
470 }
471
472 pub const fn fund(mut self, amount: U256) -> Self {
474 self.fund_amount = Some(amount);
475 self
476 }
477
478 pub const fn no_fund(mut self) -> Self {
480 self.fund_amount = None;
481 self
482 }
483}
484
485#[cfg(test)]
486mod tests {
487 use super::*;
488 use crate::{
489 fillers::{ChainIdFiller, GasFiller},
490 ProviderBuilder,
491 };
492 use alloy_eips::BlockNumberOrTag;
493 use alloy_network::TransactionBuilder;
494 use alloy_primitives::{address, B256};
495 use alloy_rpc_types_eth::TransactionRequest;
496 use alloy_sol_types::{sol, SolCall};
497
498 const FORK_URL: &str = "https://reth-ethereum.ithaca.xyz/rpc";
500
501 #[tokio::test]
502 async fn test_anvil_impersonate_account_stop_impersonating_account() {
503 let provider = ProviderBuilder::new()
504 .disable_recommended_fillers()
505 .with_simple_nonce_management()
506 .filler(GasFiller)
507 .filler(ChainIdFiller::default())
508 .connect_anvil();
509
510 let impersonate = Address::random();
511 let to = Address::random();
512 let val = U256::from(1337);
513 let funding = U256::from(1e18 as u64);
514
515 provider.anvil_set_balance(impersonate, funding).await.unwrap();
516
517 let balance = provider.get_balance(impersonate).await.unwrap();
518 assert_eq!(balance, funding);
519
520 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
521
522 let res = provider.send_transaction(tx.clone()).await;
523 res.unwrap_err();
524
525 provider.anvil_impersonate_account(impersonate).await.unwrap();
526 assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
527
528 let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
529 assert_eq!(res.from, impersonate);
530
531 let nonce = provider.get_transaction_count(impersonate).await.unwrap();
532 assert_eq!(nonce, 1);
533
534 let balance = provider.get_balance(to).await.unwrap();
535 assert_eq!(balance, val);
536
537 provider.anvil_stop_impersonating_account(impersonate).await.unwrap();
538 let res = provider.send_transaction(tx).await;
539 res.unwrap_err();
540 }
541
542 #[tokio::test]
543 async fn test_anvil_impersonated_send_with_config() {
544 let provider = ProviderBuilder::new()
545 .disable_recommended_fillers()
546 .with_simple_nonce_management()
547 .filler(GasFiller)
548 .filler(ChainIdFiller::default())
549 .connect_anvil();
550
551 let impersonate = Address::random();
552 let to = Address::random();
553 let val = U256::from(1337);
554 let funding = U256::from(1e18 as u64);
555
556 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
557
558 let config = ImpersonateConfig { fund_amount: Some(funding), stop_impersonate: true };
559
560 let pending = provider
561 .anvil_send_impersonated_transaction_with_config(tx.clone(), config)
562 .await
563 .expect("impersonated send failed");
564 let receipt = pending.get_receipt().await.unwrap();
565 assert_eq!(receipt.from, impersonate);
566
567 let recipient_balance = provider.get_balance(to).await.unwrap();
568 assert_eq!(recipient_balance, val);
569 }
570
571 #[tokio::test]
572 async fn test_anvil_auto_impersonate_account() {
573 let provider = ProviderBuilder::new()
574 .disable_recommended_fillers()
575 .with_simple_nonce_management()
576 .filler(GasFiller)
577 .filler(ChainIdFiller::default())
578 .connect_anvil();
579
580 let impersonate = Address::random();
581 let to = Address::random();
582 let val = U256::from(1337);
583 let funding = U256::from(1e18 as u64);
584
585 provider.anvil_set_balance(impersonate, funding).await.unwrap();
586
587 let balance = provider.get_balance(impersonate).await.unwrap();
588 assert_eq!(balance, funding);
589
590 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
591
592 let res = provider.send_transaction(tx.clone()).await;
593 res.unwrap_err();
594
595 provider.anvil_auto_impersonate_account(true).await.unwrap();
596
597 let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
598 assert_eq!(res.from, impersonate);
599
600 let nonce = provider.get_transaction_count(impersonate).await.unwrap();
601 assert_eq!(nonce, 1);
602
603 let balance = provider.get_balance(to).await.unwrap();
604 assert_eq!(balance, val);
605
606 provider.anvil_auto_impersonate_account(false).await.unwrap();
607 let res = provider.send_transaction(tx).await;
608 res.unwrap_err();
609
610 provider.anvil_impersonate_account(impersonate).await.unwrap();
611 assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
612 }
613
614 #[tokio::test]
615 async fn test_anvil_get_auto_mine_set_auto_mine() {
616 let provider = ProviderBuilder::new().connect_anvil();
617
618 provider.anvil_set_auto_mine(false).await.unwrap();
619
620 let enabled = provider.anvil_get_auto_mine().await.unwrap();
621 assert!(!enabled);
622
623 provider.anvil_set_auto_mine(true).await.unwrap();
624
625 let enabled = provider.anvil_get_auto_mine().await.unwrap();
626 assert!(enabled);
627 }
628
629 #[tokio::test]
630 async fn test_anvil_mine() {
631 let provider = ProviderBuilder::new().connect_anvil();
632
633 let start_num = provider.get_block_number().await.unwrap();
634
635 provider.anvil_mine(Some(10), None).await.unwrap();
636
637 let num = provider.get_block_number().await.unwrap();
638
639 assert_eq!(num, start_num + 10);
640 }
641
642 #[tokio::test]
643 async fn test_anvil_set_interval_mining() {
644 let provider = ProviderBuilder::new().connect_anvil();
645
646 provider.anvil_set_interval_mining(1).await.unwrap();
647
648 let start_num = provider.get_block_number().await.unwrap();
649
650 tokio::time::sleep(tokio::time::Duration::from_millis(1500)).await;
651
652 let num = provider.get_block_number().await.unwrap();
653
654 assert_eq!(num, start_num + 1);
655 }
656
657 #[tokio::test]
658 async fn test_anvil_drop_transaction() {
659 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
660
661 provider.anvil_set_auto_mine(false).await.unwrap();
662
663 let alice = provider.get_accounts().await.unwrap()[0];
664 let bob = provider.get_accounts().await.unwrap()[1];
665 let chain_id = provider.get_chain_id().await.unwrap();
666
667 let tx = TransactionRequest::default()
668 .with_from(alice)
669 .with_to(bob)
670 .with_nonce(0)
671 .with_chain_id(chain_id)
672 .with_value(U256::from(100))
673 .with_gas_limit(21_000)
674 .with_max_priority_fee_per_gas(1_000_000_000)
675 .with_max_fee_per_gas(20_000_000_000);
676
677 let tx_hash =
678 provider.send_transaction(tx).await.unwrap().register().await.unwrap().tx_hash;
679
680 let res = provider.anvil_drop_transaction(tx_hash).await.unwrap();
681
682 assert_eq!(res, Some(tx_hash));
683 }
684
685 #[tokio::test]
686 async fn test_anvil_drop_all_transactions() {
687 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
688
689 provider.anvil_set_auto_mine(false).await.unwrap();
690
691 let alice = provider.get_accounts().await.unwrap()[0];
692 let bob = provider.get_accounts().await.unwrap()[1];
693 let chain_id = provider.get_chain_id().await.unwrap();
694
695 let tx = TransactionRequest::default()
696 .with_from(alice)
697 .with_to(bob)
698 .with_nonce(0)
699 .with_chain_id(chain_id)
700 .with_value(U256::from(100))
701 .with_gas_limit(21_000)
702 .with_max_priority_fee_per_gas(1_000_000_000)
703 .with_max_fee_per_gas(20_000_000_000);
704
705 provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
706
707 let tx = tx.clone().with_nonce(1);
708
709 provider.send_transaction(tx).await.unwrap().register().await.unwrap();
710
711 provider.anvil_drop_all_transactions().await.unwrap();
712 }
713
714 #[tokio::test]
739 async fn test_anvil_set_chain_id() {
740 let provider = ProviderBuilder::new().connect_anvil();
741
742 let chain_id = 1337;
743 provider.anvil_set_chain_id(chain_id).await.unwrap();
744
745 let new_chain_id = provider.get_chain_id().await.unwrap();
746 assert_eq!(new_chain_id, chain_id);
747 }
748
749 #[tokio::test]
750 async fn test_anvil_set_balance() {
751 let provider = ProviderBuilder::new().connect_anvil();
752
753 let address = Address::random();
754 let balance = U256::from(1337);
755 provider.anvil_set_balance(address, balance).await.unwrap();
756
757 let new_balance = provider.get_balance(address).await.unwrap();
758 assert_eq!(new_balance, balance);
759 }
760
761 #[tokio::test]
762 async fn test_anvil_set_code() {
763 let provider = ProviderBuilder::new().connect_anvil();
764
765 let address = Address::random();
766 provider.anvil_set_code(address, Bytes::from("0xbeef")).await.unwrap();
767
768 let code = provider.get_code_at(address).await.unwrap();
769 assert_eq!(code, Bytes::from("0xbeef"));
770 }
771
772 #[tokio::test]
773 async fn test_anvil_set_nonce() {
774 let provider = ProviderBuilder::new().connect_anvil();
775
776 let address = Address::random();
777 let nonce = 1337;
778 provider.anvil_set_nonce(address, nonce).await.unwrap();
779
780 let new_nonce = provider.get_transaction_count(address).await.unwrap();
781 assert_eq!(new_nonce, nonce);
782 }
783
784 #[tokio::test]
785 async fn test_anvil_set_storage_at() {
786 let provider = ProviderBuilder::new().connect_anvil();
787
788 let address = Address::random();
789 let slot = U256::from(1337);
790 let val = B256::from(U256::from(1337));
791 provider.anvil_set_storage_at(address, slot, val).await.unwrap();
792
793 let storage = provider.get_storage_at(address, slot).await.unwrap();
794 assert_eq!(B256::from(storage), val);
795 }
796
797 #[tokio::test]
798 async fn test_anvil_set_logging() {
799 let provider = ProviderBuilder::new().connect_anvil();
800
801 provider.anvil_set_logging(true).await.unwrap();
802 }
803
804 #[tokio::test]
805 async fn test_anvil_set_min_gas_price() {
806 let provider = ProviderBuilder::new().connect_anvil();
807
808 let gas = U256::from(1337);
809
810 if let Err(e) = provider.anvil_set_min_gas_price(gas.try_into().unwrap()).await {
811 assert_eq!(
812 e.to_string(),
813 "server returned an error response: error code -32602: anvil_setMinGasPrice is not supported when EIP-1559 is active"
814 );
815 }
816 }
817
818 #[tokio::test]
819 async fn test_anvil_set_next_block_base_fee_per_gas() {
820 let provider = ProviderBuilder::new().connect_anvil();
821
822 let basefee = 1337;
823 provider.anvil_set_next_block_base_fee_per_gas(basefee).await.unwrap();
824
825 provider.evm_mine(None).await.unwrap();
826
827 let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
828
829 assert_eq!(block.header.base_fee_per_gas, Some(basefee as u64));
830 }
831
832 #[tokio::test]
833 async fn test_anvil_set_coinbase() {
834 let provider = ProviderBuilder::new().connect_anvil();
835
836 let coinbase = Address::random();
837 provider.anvil_set_coinbase(coinbase).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 assert_eq!(block.header.beneficiary, coinbase);
843 }
844
845 #[tokio::test]
846 async fn test_anvil_dump_state_load_state() {
847 let provider = ProviderBuilder::new().connect_anvil();
848
849 let state = provider.anvil_dump_state().await.unwrap();
850
851 assert!(!state.is_empty());
852
853 let res = provider.anvil_load_state(state).await.unwrap();
854
855 assert!(res);
856 }
857
858 #[tokio::test]
859 async fn test_anvil_node_info() {
860 let provider = ProviderBuilder::new().connect_anvil();
861
862 let latest_block =
863 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
864
865 provider.evm_mine(None).await.unwrap();
866
867 let node_info = provider.anvil_node_info().await.unwrap();
868
869 assert_eq!(node_info.current_block_number, latest_block.header.number + 1);
870 }
871
872 #[tokio::test]
873 async fn test_anvil_metadata() {
874 let provider = ProviderBuilder::new().connect_anvil();
875
876 let client_version = provider.get_client_version().await.unwrap();
877 let chain_id = provider.get_chain_id().await.unwrap();
878
879 let metadata = provider.anvil_metadata().await.unwrap();
880
881 assert_eq!(metadata.client_version, client_version);
882 assert_eq!(metadata.chain_id, chain_id);
883 }
884
885 #[tokio::test]
886 async fn test_anvil_remove_pool_transactions() {
887 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
888
889 provider.anvil_set_auto_mine(false).await.unwrap();
890
891 let alice = provider.get_accounts().await.unwrap()[0];
892 let bob = provider.get_accounts().await.unwrap()[1];
893 let chain_id = provider.get_chain_id().await.unwrap();
894
895 let tx = TransactionRequest::default()
896 .with_from(alice)
897 .with_to(bob)
898 .with_nonce(0)
899 .with_chain_id(chain_id)
900 .with_value(U256::from(100))
901 .with_gas_limit(21_000)
902 .with_max_priority_fee_per_gas(1_000_000_000)
903 .with_max_fee_per_gas(20_000_000_000);
904
905 provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
906
907 let tx = tx.clone().with_nonce(1);
908
909 provider.send_transaction(tx).await.unwrap().register().await.unwrap();
910
911 provider.anvil_remove_pool_transactions(alice).await.unwrap();
912 }
913
914 #[tokio::test]
915 async fn test_anvil_snapshot_revert() {
916 let provider = ProviderBuilder::new().connect_anvil();
917
918 let snapshot_id = provider.anvil_snapshot().await.unwrap();
919
920 let alice = provider.get_accounts().await.unwrap()[0];
921 let bob = provider.get_accounts().await.unwrap()[1];
922 let chain_id = provider.get_chain_id().await.unwrap();
923
924 let tx = TransactionRequest::default()
925 .with_from(alice)
926 .with_to(bob)
927 .with_nonce(0)
928 .with_chain_id(chain_id)
929 .with_value(U256::from(100))
930 .with_gas_limit(21_000)
931 .with_max_priority_fee_per_gas(1_000_000_000)
932 .with_max_fee_per_gas(20_000_000_000);
933
934 provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
935
936 let tx = tx.clone().with_nonce(1);
937
938 provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap();
939
940 let tx_count = provider.get_transaction_count(alice).await.unwrap();
941 assert_eq!(tx_count, 2);
942
943 let res = provider.anvil_revert(snapshot_id).await.unwrap();
944 assert!(res);
945
946 let tx_count = provider.get_transaction_count(alice).await.unwrap();
947 assert_eq!(tx_count, 0);
948 }
949
950 #[tokio::test]
951 async fn test_anvil_increase_time() {
952 let provider = ProviderBuilder::new().connect_anvil();
953
954 let timestamp = provider
955 .get_block_by_number(BlockNumberOrTag::Latest)
956 .await
957 .unwrap()
958 .unwrap()
959 .header
960 .timestamp;
961
962 let seconds = provider.anvil_increase_time(1337).await.unwrap();
963
964 assert_eq!(timestamp as i64 + seconds, timestamp as i64 + 1337_i64);
965 }
966
967 #[tokio::test]
968 async fn test_anvil_set_next_block_timestamp() {
969 let provider = ProviderBuilder::new().connect_anvil();
970
971 let timestamp = provider
972 .get_block_by_number(BlockNumberOrTag::Latest)
973 .await
974 .unwrap()
975 .unwrap()
976 .header
977 .timestamp;
978
979 provider.anvil_set_next_block_timestamp(timestamp + 1337).await.unwrap();
980
981 provider.evm_mine(None).await.unwrap();
982
983 let latest_block =
984 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
985 assert_eq!(latest_block.header.timestamp, timestamp + 1337);
986 }
987
988 #[tokio::test]
989 async fn test_anvil_set_time() {
990 let provider = ProviderBuilder::new().connect_anvil();
991
992 provider.anvil_set_time(0).await.unwrap();
993
994 let seconds = provider.anvil_set_time(1001).await.unwrap();
995
996 assert_eq!(seconds, 1);
997 }
998
999 #[tokio::test]
1000 async fn test_anvil_set_block_gas_limit() {
1001 let provider = ProviderBuilder::new().connect_anvil();
1002
1003 let block_gas_limit = 1337;
1004 assert!(provider.anvil_set_block_gas_limit(block_gas_limit).await.unwrap());
1005
1006 provider.evm_mine(None).await.unwrap();
1007
1008 let latest_block =
1009 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1010 assert_eq!(block_gas_limit, latest_block.header.gas_limit);
1011 }
1012
1013 #[tokio::test]
1014 async fn test_anvil_block_timestamp_interval() {
1015 let provider = ProviderBuilder::new().connect_anvil();
1016
1017 provider.anvil_set_block_timestamp_interval(1).await.unwrap();
1018
1019 let start_timestamp = provider
1020 .get_block_by_number(BlockNumberOrTag::Latest)
1021 .await
1022 .unwrap()
1023 .unwrap()
1024 .header
1025 .timestamp;
1026
1027 tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1028
1029 provider.evm_mine(None).await.unwrap();
1030
1031 let latest_block =
1032 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1033
1034 assert_eq!(latest_block.header.timestamp, start_timestamp + 1);
1035
1036 provider.anvil_remove_block_timestamp_interval().await.unwrap();
1037
1038 provider.evm_mine(None).await.unwrap();
1039
1040 let start_timestamp = provider
1041 .get_block_by_number(BlockNumberOrTag::Latest)
1042 .await
1043 .unwrap()
1044 .unwrap()
1045 .header
1046 .timestamp;
1047
1048 tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
1049
1050 let latest_block =
1051 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1052
1053 assert_eq!(latest_block.header.timestamp, start_timestamp);
1054 }
1055
1056 #[tokio::test]
1057 async fn test_evm_mine_single_block() {
1058 let provider = ProviderBuilder::new().connect_anvil();
1059
1060 let start_num = provider.get_block_number().await.unwrap();
1061
1062 for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1063 provider.evm_mine(None).await.unwrap();
1064 let num = provider.get_block_number().await.unwrap();
1065 assert_eq!(num, start_num + idx as u64 + 1);
1066 }
1067
1068 let num = provider.get_block_number().await.unwrap();
1069 assert_eq!(num, start_num + 10);
1070 }
1071
1072 #[tokio::test]
1089 async fn test_anvil_mine_detailed_single_block() {
1090 let provider = ProviderBuilder::new().connect_anvil();
1091
1092 let start_num = provider.get_block_number().await.unwrap();
1093
1094 for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
1095 provider.anvil_mine_detailed(None).await.unwrap();
1096 let num = provider.get_block_number().await.unwrap();
1097 assert_eq!(num, start_num + idx as u64 + 1);
1098 }
1099
1100 let num = provider.get_block_number().await.unwrap();
1101 assert_eq!(num, start_num + 10);
1102 }
1103
1104 #[tokio::test]
1128 async fn test_anvil_set_rpc_url() {
1129 let provider = ProviderBuilder::new().connect_anvil();
1130
1131 let url = "https://example.com".to_string();
1132 provider.anvil_set_rpc_url(url.clone()).await.unwrap();
1133 }
1134
1135 #[tokio::test]
1136 async fn test_anvil_reorg() {
1137 let provider = ProviderBuilder::new().connect_anvil();
1138
1139 provider.anvil_mine(Some(2), None).await.unwrap();
1141
1142 let reorged_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1143 provider.anvil_reorg(ReorgOptions { depth: 1, tx_block_pairs: Vec::new() }).await.unwrap();
1144
1145 let new_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1146
1147 assert_eq!(reorged_block.header.number, new_block.header.number);
1148 assert_ne!(reorged_block.header.hash, new_block.header.hash);
1149 }
1150
1151 #[tokio::test]
1152 #[ignore]
1153 async fn test_anvil_rollback() {
1154 let provider = ProviderBuilder::new().connect_anvil();
1155
1156 provider.anvil_mine(Some(2), None).await.unwrap();
1158
1159 let target_height = provider.get_block_by_number(1.into()).await.unwrap().unwrap();
1160
1161 provider.anvil_rollback(Some(1)).await.unwrap();
1162
1163 let new_head =
1164 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1165
1166 assert_eq!(target_height, new_head);
1167 }
1168
1169 #[tokio::test]
1170 async fn test_eth_send_unsigned_transaction() {
1171 let provider = ProviderBuilder::new().connect_anvil();
1172
1173 let alice = Address::random();
1174 let bob = Address::random();
1175 let chain_id = provider.get_chain_id().await.unwrap();
1176
1177 provider.anvil_set_balance(alice, U256::from(1e18 as u64)).await.unwrap();
1178
1179 let tx = TransactionRequest::default()
1180 .with_from(alice)
1181 .with_to(bob)
1182 .with_nonce(0)
1183 .with_chain_id(chain_id)
1184 .with_value(U256::from(100))
1185 .with_gas_limit(21_000)
1186 .with_max_priority_fee_per_gas(1_000_000_000)
1187 .with_max_fee_per_gas(20_000_000_000);
1188
1189 let tx_hash = provider.eth_send_unsigned_transaction(tx).await.unwrap();
1190
1191 provider.evm_mine(None).await.unwrap();
1192
1193 let res = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap();
1194 assert_eq!(res.from, alice);
1195 assert_eq!(res.to, Some(bob));
1196 }
1197
1198 #[tokio::test]
1199 async fn test_anvil_deal_erc20() {
1200 let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1201
1202 let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1203 let user = Address::random();
1204 let amount = U256::from(1e18 as u64);
1205
1206 provider.anvil_deal_erc20(user, dai, amount).await.unwrap();
1207
1208 sol! {
1209 function balanceOf(address owner) view returns (uint256);
1210 }
1211
1212 let balance_of_call = balanceOfCall::new((user,));
1213 let input = balanceOfCall::abi_encode(&balance_of_call);
1214
1215 let result = provider
1216 .call(TransactionRequest::default().with_to(dai).with_input(input))
1217 .await
1218 .unwrap();
1219 let balance = balanceOfCall::abi_decode_returns(&result).unwrap();
1220
1221 assert_eq!(balance, amount);
1222 }
1223
1224 #[tokio::test]
1225 async fn test_anvil_set_erc20_allowance() {
1226 let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1227
1228 let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1229 let owner = Address::random();
1230 let spender = Address::random();
1231 let amount = U256::from(1e18 as u64);
1232
1233 provider.anvil_set_erc20_allowance(owner, spender, dai, amount).await.unwrap();
1234
1235 sol! {
1236 function allowance(address owner, address spender) view returns (uint256);
1237 }
1238
1239 let allowance_call = allowanceCall::new((owner, spender));
1240 let input = allowanceCall::abi_encode(&allowance_call);
1241
1242 let result = provider
1243 .call(TransactionRequest::default().with_to(dai).with_input(input))
1244 .await
1245 .unwrap();
1246 let allowance = allowanceCall::abi_decode_returns(&result).unwrap();
1247
1248 assert_eq!(allowance, amount);
1249 }
1250}