1use crate::Provider;
4use alloy_network::Network;
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::TransportResult;
9
10#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
12#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
13pub trait AnvilApi<N: Network>: Send + Sync {
14 async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()>;
20
21 async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()>;
23
24 async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()>;
26
27 async fn anvil_get_auto_mine(&self) -> TransportResult<bool>;
29
30 async fn anvil_set_auto_mine(&self, enable_automine: bool) -> TransportResult<()>;
33
34 async fn anvil_mine(
36 &self,
37 num_blocks: Option<u64>,
38 interval: Option<u64>,
39 ) -> TransportResult<()>;
40
41 async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()>;
43
44 async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>>;
46
47 async fn anvil_drop_all_transactions(&self) -> TransportResult<()>;
49
50 async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()>;
54
55 async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()>;
57
58 async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()>;
60
61 async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()>;
63
64 async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()>;
66
67 async fn anvil_set_storage_at(
69 &self,
70 address: Address,
71 slot: U256,
72 val: B256,
73 ) -> TransportResult<bool>;
74
75 async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()>;
77
78 async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()>;
80
81 async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()>;
83
84 async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()>;
86
87 async fn anvil_dump_state(&self) -> TransportResult<Bytes>;
90
91 async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool>;
94
95 async fn anvil_node_info(&self) -> TransportResult<NodeInfo>;
97
98 async fn anvil_metadata(&self) -> TransportResult<Metadata>;
100
101 async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()>;
103
104 async fn anvil_snapshot(&self) -> TransportResult<U256>;
106
107 async fn anvil_revert(&self, id: U256) -> TransportResult<bool>;
110
111 async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64>;
113
114 async fn anvil_set_next_block_timestamp(&self, timestamp: u64) -> TransportResult<()>;
116
117 async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64>;
120
121 async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool>;
123
124 async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()>;
126
127 async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool>;
129
130 async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String>;
133
134 async fn anvil_mine_detailed(&self, opts: Option<MineOptions>) -> TransportResult<Vec<Block>>;
137
138 async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()>;
140
141 async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()>;
143
144 async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()>;
146
147 async fn eth_send_unsigned_transaction(
149 &self,
150 request: N::TransactionRequest,
151 ) -> TransportResult<TxHash>;
152
153 async fn anvil_send_impersonated_transaction(
155 &self,
156 request: N::TransactionRequest,
157 ) -> TransportResult<TxHash>;
158
159 async fn anvil_deal_erc20(
161 &self,
162 address: Address,
163 token_address: Address,
164 balance: U256,
165 ) -> TransportResult<()>;
166
167 async fn anvil_set_erc20_allowance(
169 &self,
170 owner: Address,
171 spender: Address,
172 token: Address,
173 allowance: U256,
174 ) -> TransportResult<()>;
175}
176
177#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
178#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
179impl<N, P> AnvilApi<N> for P
180where
181 N: Network,
182 P: Provider<N>,
183{
184 async fn anvil_impersonate_account(&self, address: Address) -> TransportResult<()> {
185 self.client().request("anvil_impersonateAccount", (address,)).await
186 }
187
188 async fn anvil_stop_impersonating_account(&self, address: Address) -> TransportResult<()> {
189 self.client().request("anvil_stopImpersonatingAccount", (address,)).await
190 }
191
192 async fn anvil_auto_impersonate_account(&self, enabled: bool) -> TransportResult<()> {
193 self.client().request("anvil_autoImpersonateAccount", (enabled,)).await
194 }
195
196 async fn anvil_get_auto_mine(&self) -> TransportResult<bool> {
197 self.client().request_noparams("anvil_getAutomine").await
198 }
199
200 async fn anvil_set_auto_mine(&self, enabled: bool) -> TransportResult<()> {
201 self.client().request("anvil_setAutomine", (enabled,)).await
202 }
203
204 async fn anvil_mine(
205 &self,
206 num_blocks: Option<u64>,
207 interval: Option<u64>,
208 ) -> TransportResult<()> {
209 self.client()
210 .request("anvil_mine", (num_blocks.map(U64::from), interval.map(U64::from)))
211 .await
212 }
213
214 async fn anvil_set_interval_mining(&self, secs: u64) -> TransportResult<()> {
215 self.client().request("anvil_setIntervalMining", (secs,)).await
216 }
217
218 async fn anvil_drop_transaction(&self, tx_hash: TxHash) -> TransportResult<Option<TxHash>> {
219 self.client().request("anvil_dropTransaction", (tx_hash,)).await
220 }
221
222 async fn anvil_drop_all_transactions(&self) -> TransportResult<()> {
223 self.client().request_noparams("anvil_dropAllTransactions").await
224 }
225
226 async fn anvil_reset(&self, forking: Option<Forking>) -> TransportResult<()> {
227 self.client().request("anvil_reset", (forking,)).await
228 }
229
230 async fn anvil_set_chain_id(&self, chain_id: u64) -> TransportResult<()> {
231 self.client().request("anvil_setChainId", (chain_id,)).await
232 }
233
234 async fn anvil_set_balance(&self, address: Address, balance: U256) -> TransportResult<()> {
235 self.client().request("anvil_setBalance", (address, balance)).await
236 }
237
238 async fn anvil_set_code(&self, address: Address, code: Bytes) -> TransportResult<()> {
239 self.client().request("anvil_setCode", (address, code)).await
240 }
241
242 async fn anvil_set_nonce(&self, address: Address, nonce: u64) -> TransportResult<()> {
243 self.client().request("anvil_setNonce", (address, U64::from(nonce))).await
244 }
245
246 async fn anvil_set_storage_at(
247 &self,
248 address: Address,
249 slot: U256,
250 val: B256,
251 ) -> TransportResult<bool> {
252 self.client().request("anvil_setStorageAt", (address, slot, val)).await
253 }
254
255 async fn anvil_set_logging(&self, enable: bool) -> TransportResult<()> {
256 self.client().request("anvil_setLoggingEnabled", (enable,)).await
257 }
258
259 async fn anvil_set_min_gas_price(&self, gas: u128) -> TransportResult<()> {
260 self.client().request("anvil_setMinGasPrice", (U128::from(gas),)).await
261 }
262
263 async fn anvil_set_next_block_base_fee_per_gas(&self, basefee: u128) -> TransportResult<()> {
264 self.client().request("anvil_setNextBlockBaseFeePerGas", (U128::from(basefee),)).await
265 }
266
267 async fn anvil_set_coinbase(&self, address: Address) -> TransportResult<()> {
268 self.client().request("anvil_setCoinbase", (address,)).await
269 }
270
271 async fn anvil_dump_state(&self) -> TransportResult<Bytes> {
272 self.client().request_noparams("anvil_dumpState").await
273 }
274
275 async fn anvil_load_state(&self, buf: Bytes) -> TransportResult<bool> {
276 self.client().request("anvil_loadState", (buf,)).await
277 }
278
279 async fn anvil_node_info(&self) -> TransportResult<NodeInfo> {
280 self.client().request_noparams("anvil_nodeInfo").await
281 }
282
283 async fn anvil_metadata(&self) -> TransportResult<Metadata> {
284 self.client().request_noparams("anvil_metadata").await
285 }
286
287 async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()> {
288 self.client().request("anvil_removePoolTransactions", (address,)).await
289 }
290
291 async fn anvil_snapshot(&self) -> TransportResult<U256> {
292 self.client().request_noparams("evm_snapshot").await
293 }
294
295 async fn anvil_revert(&self, id: U256) -> TransportResult<bool> {
296 self.client().request("evm_revert", (id,)).await
297 }
298
299 async fn anvil_increase_time(&self, seconds: u64) -> TransportResult<i64> {
300 self.client().request("evm_increaseTime", (U64::from(seconds),)).await
301 }
302
303 async fn anvil_set_next_block_timestamp(&self, seconds: u64) -> TransportResult<()> {
304 self.client().request("evm_setNextBlockTimestamp", (seconds,)).await
305 }
306
307 async fn anvil_set_time(&self, timestamp: u64) -> TransportResult<u64> {
308 self.client().request("evm_setTime", (timestamp,)).await
309 }
310
311 async fn anvil_set_block_gas_limit(&self, gas_limit: u64) -> TransportResult<bool> {
312 self.client().request("evm_setBlockGasLimit", (U64::from(gas_limit),)).await
313 }
314
315 async fn anvil_set_block_timestamp_interval(&self, seconds: u64) -> TransportResult<()> {
316 self.client().request("anvil_setBlockTimestampInterval", (seconds,)).await
317 }
318
319 async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult<bool> {
320 self.client().request_noparams("anvil_removeBlockTimestampInterval").await
321 }
322
323 async fn evm_mine(&self, opts: Option<MineOptions>) -> TransportResult<String> {
324 self.client().request("evm_mine", (opts,)).await
325 }
326
327 async fn anvil_mine_detailed(&self, opts: Option<MineOptions>) -> TransportResult<Vec<Block>> {
328 self.client().request("evm_mine_detailed", (opts,)).await
329 }
330
331 async fn anvil_set_rpc_url(&self, url: String) -> TransportResult<()> {
332 self.client().request("anvil_setRpcUrl", (url,)).await
333 }
334
335 async fn anvil_reorg(&self, options: ReorgOptions) -> TransportResult<()> {
336 self.client().request("anvil_reorg", options).await
337 }
338
339 async fn anvil_rollback(&self, depth: Option<u64>) -> TransportResult<()> {
340 self.client().request("anvil_rollback", (depth,)).await
341 }
342
343 async fn eth_send_unsigned_transaction(
344 &self,
345 request: N::TransactionRequest,
346 ) -> TransportResult<TxHash> {
347 self.client().request("eth_sendUnsignedTransaction", (request,)).await
348 }
349
350 async fn anvil_send_impersonated_transaction(
351 &self,
352 request: N::TransactionRequest,
353 ) -> TransportResult<TxHash> {
354 self.client().request("eth_sendTransaction", (request,)).await
355 }
356
357 async fn anvil_deal_erc20(
358 &self,
359 address: Address,
360 token_address: Address,
361 balance: U256,
362 ) -> TransportResult<()> {
363 self.client().request("anvil_dealERC20", (address, token_address, balance)).await
364 }
365
366 async fn anvil_set_erc20_allowance(
367 &self,
368 owner: Address,
369 spender: Address,
370 token: Address,
371 allowance: U256,
372 ) -> TransportResult<()> {
373 self.client().request("anvil_setERC20Allowance", (owner, spender, token, allowance)).await
374 }
375}
376
377#[cfg(test)]
378mod tests {
379 use super::*;
380 use crate::{
381 fillers::{ChainIdFiller, GasFiller},
382 ProviderBuilder,
383 };
384 use alloy_eips::BlockNumberOrTag;
385 use alloy_network::TransactionBuilder;
386 use alloy_primitives::{address, B256};
387 use alloy_rpc_types_eth::TransactionRequest;
388 use alloy_sol_types::{sol, SolCall};
389
390 const FORK_URL: &str = "https://reth-ethereum.ithaca.xyz/rpc";
392
393 #[tokio::test]
394 async fn test_anvil_impersonate_account_stop_impersonating_account() {
395 let provider = ProviderBuilder::new()
396 .disable_recommended_fillers()
397 .with_simple_nonce_management()
398 .filler(GasFiller)
399 .filler(ChainIdFiller::default())
400 .connect_anvil();
401
402 let impersonate = Address::random();
403 let to = Address::random();
404 let val = U256::from(1337);
405 let funding = U256::from(1e18 as u64);
406
407 provider.anvil_set_balance(impersonate, funding).await.unwrap();
408
409 let balance = provider.get_balance(impersonate).await.unwrap();
410 assert_eq!(balance, funding);
411
412 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
413
414 let res = provider.send_transaction(tx.clone()).await;
415 res.unwrap_err();
416
417 provider.anvil_impersonate_account(impersonate).await.unwrap();
418 assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
419
420 let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
421 assert_eq!(res.from, impersonate);
422
423 let nonce = provider.get_transaction_count(impersonate).await.unwrap();
424 assert_eq!(nonce, 1);
425
426 let balance = provider.get_balance(to).await.unwrap();
427 assert_eq!(balance, val);
428
429 provider.anvil_stop_impersonating_account(impersonate).await.unwrap();
430 let res = provider.send_transaction(tx).await;
431 res.unwrap_err();
432 }
433
434 #[tokio::test]
435 async fn test_anvil_auto_impersonate_account() {
436 let provider = ProviderBuilder::new()
437 .disable_recommended_fillers()
438 .with_simple_nonce_management()
439 .filler(GasFiller)
440 .filler(ChainIdFiller::default())
441 .connect_anvil();
442
443 let impersonate = Address::random();
444 let to = Address::random();
445 let val = U256::from(1337);
446 let funding = U256::from(1e18 as u64);
447
448 provider.anvil_set_balance(impersonate, funding).await.unwrap();
449
450 let balance = provider.get_balance(impersonate).await.unwrap();
451 assert_eq!(balance, funding);
452
453 let tx = TransactionRequest::default().with_from(impersonate).with_to(to).with_value(val);
454
455 let res = provider.send_transaction(tx.clone()).await;
456 res.unwrap_err();
457
458 provider.anvil_auto_impersonate_account(true).await.unwrap();
459
460 let res = provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
461 assert_eq!(res.from, impersonate);
462
463 let nonce = provider.get_transaction_count(impersonate).await.unwrap();
464 assert_eq!(nonce, 1);
465
466 let balance = provider.get_balance(to).await.unwrap();
467 assert_eq!(balance, val);
468
469 provider.anvil_auto_impersonate_account(false).await.unwrap();
470 let res = provider.send_transaction(tx).await;
471 res.unwrap_err();
472
473 provider.anvil_impersonate_account(impersonate).await.unwrap();
474 assert!(provider.get_accounts().await.unwrap().contains(&impersonate));
475 }
476
477 #[tokio::test]
478 async fn test_anvil_get_auto_mine_set_auto_mine() {
479 let provider = ProviderBuilder::new().connect_anvil();
480
481 provider.anvil_set_auto_mine(false).await.unwrap();
482
483 let enabled = provider.anvil_get_auto_mine().await.unwrap();
484 assert!(!enabled);
485
486 provider.anvil_set_auto_mine(true).await.unwrap();
487
488 let enabled = provider.anvil_get_auto_mine().await.unwrap();
489 assert!(enabled);
490 }
491
492 #[tokio::test]
493 async fn test_anvil_mine() {
494 let provider = ProviderBuilder::new().connect_anvil();
495
496 let start_num = provider.get_block_number().await.unwrap();
497
498 provider.anvil_mine(Some(10), None).await.unwrap();
499
500 let num = provider.get_block_number().await.unwrap();
501
502 assert_eq!(num, start_num + 10);
503 }
504
505 #[tokio::test]
506 async fn test_anvil_set_interval_mining() {
507 let provider = ProviderBuilder::new().connect_anvil();
508
509 provider.anvil_set_interval_mining(1).await.unwrap();
510
511 let start_num = provider.get_block_number().await.unwrap();
512
513 tokio::time::sleep(tokio::time::Duration::from_millis(1500)).await;
514
515 let num = provider.get_block_number().await.unwrap();
516
517 assert_eq!(num, start_num + 1);
518 }
519
520 #[tokio::test]
521 async fn test_anvil_drop_transaction() {
522 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
523
524 provider.anvil_set_auto_mine(false).await.unwrap();
525
526 let alice = provider.get_accounts().await.unwrap()[0];
527 let bob = provider.get_accounts().await.unwrap()[1];
528 let chain_id = provider.get_chain_id().await.unwrap();
529
530 let tx = TransactionRequest::default()
531 .with_from(alice)
532 .with_to(bob)
533 .with_nonce(0)
534 .with_chain_id(chain_id)
535 .with_value(U256::from(100))
536 .with_gas_limit(21_000)
537 .with_max_priority_fee_per_gas(1_000_000_000)
538 .with_max_fee_per_gas(20_000_000_000);
539
540 let tx_hash =
541 provider.send_transaction(tx).await.unwrap().register().await.unwrap().tx_hash;
542
543 let res = provider.anvil_drop_transaction(tx_hash).await.unwrap();
544
545 assert_eq!(res, Some(tx_hash));
546 }
547
548 #[tokio::test]
549 async fn test_anvil_drop_all_transactions() {
550 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
551
552 provider.anvil_set_auto_mine(false).await.unwrap();
553
554 let alice = provider.get_accounts().await.unwrap()[0];
555 let bob = provider.get_accounts().await.unwrap()[1];
556 let chain_id = provider.get_chain_id().await.unwrap();
557
558 let tx = TransactionRequest::default()
559 .with_from(alice)
560 .with_to(bob)
561 .with_nonce(0)
562 .with_chain_id(chain_id)
563 .with_value(U256::from(100))
564 .with_gas_limit(21_000)
565 .with_max_priority_fee_per_gas(1_000_000_000)
566 .with_max_fee_per_gas(20_000_000_000);
567
568 provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
569
570 let tx = tx.clone().with_nonce(1);
571
572 provider.send_transaction(tx).await.unwrap().register().await.unwrap();
573
574 provider.anvil_drop_all_transactions().await.unwrap();
575 }
576
577 #[tokio::test]
602 async fn test_anvil_set_chain_id() {
603 let provider = ProviderBuilder::new().connect_anvil();
604
605 let chain_id = 1337;
606 provider.anvil_set_chain_id(chain_id).await.unwrap();
607
608 let new_chain_id = provider.get_chain_id().await.unwrap();
609 assert_eq!(new_chain_id, chain_id);
610 }
611
612 #[tokio::test]
613 async fn test_anvil_set_balance() {
614 let provider = ProviderBuilder::new().connect_anvil();
615
616 let address = Address::random();
617 let balance = U256::from(1337);
618 provider.anvil_set_balance(address, balance).await.unwrap();
619
620 let new_balance = provider.get_balance(address).await.unwrap();
621 assert_eq!(new_balance, balance);
622 }
623
624 #[tokio::test]
625 async fn test_anvil_set_code() {
626 let provider = ProviderBuilder::new().connect_anvil();
627
628 let address = Address::random();
629 provider.anvil_set_code(address, Bytes::from("0xbeef")).await.unwrap();
630
631 let code = provider.get_code_at(address).await.unwrap();
632 assert_eq!(code, Bytes::from("0xbeef"));
633 }
634
635 #[tokio::test]
636 async fn test_anvil_set_nonce() {
637 let provider = ProviderBuilder::new().connect_anvil();
638
639 let address = Address::random();
640 let nonce = 1337;
641 provider.anvil_set_nonce(address, nonce).await.unwrap();
642
643 let new_nonce = provider.get_transaction_count(address).await.unwrap();
644 assert_eq!(new_nonce, nonce);
645 }
646
647 #[tokio::test]
648 async fn test_anvil_set_storage_at() {
649 let provider = ProviderBuilder::new().connect_anvil();
650
651 let address = Address::random();
652 let slot = U256::from(1337);
653 let val = B256::from(U256::from(1337));
654 provider.anvil_set_storage_at(address, slot, val).await.unwrap();
655
656 let storage = provider.get_storage_at(address, slot).await.unwrap();
657 assert_eq!(B256::from(storage), val);
658 }
659
660 #[tokio::test]
661 async fn test_anvil_set_logging() {
662 let provider = ProviderBuilder::new().connect_anvil();
663
664 provider.anvil_set_logging(true).await.unwrap();
665 }
666
667 #[tokio::test]
668 async fn test_anvil_set_min_gas_price() {
669 let provider = ProviderBuilder::new().connect_anvil();
670
671 let gas = U256::from(1337);
672
673 if let Err(e) = provider.anvil_set_min_gas_price(gas.try_into().unwrap()).await {
674 assert_eq!(
675 e.to_string(),
676 "server returned an error response: error code -32602: anvil_setMinGasPrice is not supported when EIP-1559 is active"
677 );
678 }
679 }
680
681 #[tokio::test]
682 async fn test_anvil_set_next_block_base_fee_per_gas() {
683 let provider = ProviderBuilder::new().connect_anvil();
684
685 let basefee = 1337;
686 provider.anvil_set_next_block_base_fee_per_gas(basefee).await.unwrap();
687
688 provider.evm_mine(None).await.unwrap();
689
690 let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
691
692 assert_eq!(block.header.base_fee_per_gas, Some(basefee as u64));
693 }
694
695 #[tokio::test]
696 async fn test_anvil_set_coinbase() {
697 let provider = ProviderBuilder::new().connect_anvil();
698
699 let coinbase = Address::random();
700 provider.anvil_set_coinbase(coinbase).await.unwrap();
701
702 provider.evm_mine(None).await.unwrap();
703
704 let block = provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
705 assert_eq!(block.header.beneficiary, coinbase);
706 }
707
708 #[tokio::test]
709 async fn test_anvil_dump_state_load_state() {
710 let provider = ProviderBuilder::new().connect_anvil();
711
712 let state = provider.anvil_dump_state().await.unwrap();
713
714 assert!(!state.is_empty());
715
716 let res = provider.anvil_load_state(state).await.unwrap();
717
718 assert!(res);
719 }
720
721 #[tokio::test]
722 async fn test_anvil_node_info() {
723 let provider = ProviderBuilder::new().connect_anvil();
724
725 let latest_block =
726 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
727
728 provider.evm_mine(None).await.unwrap();
729
730 let node_info = provider.anvil_node_info().await.unwrap();
731
732 assert_eq!(node_info.current_block_number, latest_block.header.number + 1);
733 }
734
735 #[tokio::test]
736 async fn test_anvil_metadata() {
737 let provider = ProviderBuilder::new().connect_anvil();
738
739 let client_version = provider.get_client_version().await.unwrap();
740 let chain_id = provider.get_chain_id().await.unwrap();
741
742 let metadata = provider.anvil_metadata().await.unwrap();
743
744 assert_eq!(metadata.client_version, client_version);
745 assert_eq!(metadata.chain_id, chain_id);
746 }
747
748 #[tokio::test]
749 async fn test_anvil_remove_pool_transactions() {
750 let provider = ProviderBuilder::new().connect_anvil_with_wallet();
751
752 provider.anvil_set_auto_mine(false).await.unwrap();
753
754 let alice = provider.get_accounts().await.unwrap()[0];
755 let bob = provider.get_accounts().await.unwrap()[1];
756 let chain_id = provider.get_chain_id().await.unwrap();
757
758 let tx = TransactionRequest::default()
759 .with_from(alice)
760 .with_to(bob)
761 .with_nonce(0)
762 .with_chain_id(chain_id)
763 .with_value(U256::from(100))
764 .with_gas_limit(21_000)
765 .with_max_priority_fee_per_gas(1_000_000_000)
766 .with_max_fee_per_gas(20_000_000_000);
767
768 provider.send_transaction(tx.clone()).await.unwrap().register().await.unwrap();
769
770 let tx = tx.clone().with_nonce(1);
771
772 provider.send_transaction(tx).await.unwrap().register().await.unwrap();
773
774 provider.anvil_remove_pool_transactions(alice).await.unwrap();
775 }
776
777 #[tokio::test]
778 async fn test_anvil_snapshot_revert() {
779 let provider = ProviderBuilder::new().connect_anvil();
780
781 let snapshot_id = provider.anvil_snapshot().await.unwrap();
782
783 let alice = provider.get_accounts().await.unwrap()[0];
784 let bob = provider.get_accounts().await.unwrap()[1];
785 let chain_id = provider.get_chain_id().await.unwrap();
786
787 let tx = TransactionRequest::default()
788 .with_from(alice)
789 .with_to(bob)
790 .with_nonce(0)
791 .with_chain_id(chain_id)
792 .with_value(U256::from(100))
793 .with_gas_limit(21_000)
794 .with_max_priority_fee_per_gas(1_000_000_000)
795 .with_max_fee_per_gas(20_000_000_000);
796
797 provider.send_transaction(tx.clone()).await.unwrap().get_receipt().await.unwrap();
798
799 let tx = tx.clone().with_nonce(1);
800
801 provider.send_transaction(tx).await.unwrap().get_receipt().await.unwrap();
802
803 let tx_count = provider.get_transaction_count(alice).await.unwrap();
804 assert_eq!(tx_count, 2);
805
806 let res = provider.anvil_revert(snapshot_id).await.unwrap();
807 assert!(res);
808
809 let tx_count = provider.get_transaction_count(alice).await.unwrap();
810 assert_eq!(tx_count, 0);
811 }
812
813 #[tokio::test]
814 async fn test_anvil_increase_time() {
815 let provider = ProviderBuilder::new().connect_anvil();
816
817 let timestamp = provider
818 .get_block_by_number(BlockNumberOrTag::Latest)
819 .await
820 .unwrap()
821 .unwrap()
822 .header
823 .timestamp;
824
825 let seconds = provider.anvil_increase_time(1337).await.unwrap();
826
827 assert_eq!(timestamp as i64 + seconds, timestamp as i64 + 1337_i64);
828 }
829
830 #[tokio::test]
831 async fn test_anvil_set_next_block_timestamp() {
832 let provider = ProviderBuilder::new().connect_anvil();
833
834 let timestamp = provider
835 .get_block_by_number(BlockNumberOrTag::Latest)
836 .await
837 .unwrap()
838 .unwrap()
839 .header
840 .timestamp;
841
842 provider.anvil_set_next_block_timestamp(timestamp + 1337).await.unwrap();
843
844 provider.evm_mine(None).await.unwrap();
845
846 let latest_block =
847 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
848 assert_eq!(latest_block.header.timestamp, timestamp + 1337);
849 }
850
851 #[tokio::test]
852 async fn test_anvil_set_time() {
853 let provider = ProviderBuilder::new().connect_anvil();
854
855 provider.anvil_set_time(0).await.unwrap();
856
857 let seconds = provider.anvil_set_time(1001).await.unwrap();
858
859 assert_eq!(seconds, 1);
860 }
861
862 #[tokio::test]
863 async fn test_anvil_set_block_gas_limit() {
864 let provider = ProviderBuilder::new().connect_anvil();
865
866 let block_gas_limit = 1337;
867 assert!(provider.anvil_set_block_gas_limit(block_gas_limit).await.unwrap());
868
869 provider.evm_mine(None).await.unwrap();
870
871 let latest_block =
872 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
873 assert_eq!(block_gas_limit, latest_block.header.gas_limit);
874 }
875
876 #[tokio::test]
877 async fn test_anvil_block_timestamp_interval() {
878 let provider = ProviderBuilder::new().connect_anvil();
879
880 provider.anvil_set_block_timestamp_interval(1).await.unwrap();
881
882 let start_timestamp = provider
883 .get_block_by_number(BlockNumberOrTag::Latest)
884 .await
885 .unwrap()
886 .unwrap()
887 .header
888 .timestamp;
889
890 tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
891
892 provider.evm_mine(None).await.unwrap();
893
894 let latest_block =
895 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
896
897 assert_eq!(latest_block.header.timestamp, start_timestamp + 1);
898
899 provider.anvil_remove_block_timestamp_interval().await.unwrap();
900
901 provider.evm_mine(None).await.unwrap();
902
903 let start_timestamp = provider
904 .get_block_by_number(BlockNumberOrTag::Latest)
905 .await
906 .unwrap()
907 .unwrap()
908 .header
909 .timestamp;
910
911 tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
912
913 let latest_block =
914 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
915
916 assert_eq!(latest_block.header.timestamp, start_timestamp);
917 }
918
919 #[tokio::test]
920 async fn test_evm_mine_single_block() {
921 let provider = ProviderBuilder::new().connect_anvil();
922
923 let start_num = provider.get_block_number().await.unwrap();
924
925 for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
926 provider.evm_mine(None).await.unwrap();
927 let num = provider.get_block_number().await.unwrap();
928 assert_eq!(num, start_num + idx as u64 + 1);
929 }
930
931 let num = provider.get_block_number().await.unwrap();
932 assert_eq!(num, start_num + 10);
933 }
934
935 #[tokio::test]
952 async fn test_anvil_mine_detailed_single_block() {
953 let provider = ProviderBuilder::new().connect_anvil();
954
955 let start_num = provider.get_block_number().await.unwrap();
956
957 for (idx, _) in std::iter::repeat_n((), 10).enumerate() {
958 provider.anvil_mine_detailed(None).await.unwrap();
959 let num = provider.get_block_number().await.unwrap();
960 assert_eq!(num, start_num + idx as u64 + 1);
961 }
962
963 let num = provider.get_block_number().await.unwrap();
964 assert_eq!(num, start_num + 10);
965 }
966
967 #[tokio::test]
991 async fn test_anvil_set_rpc_url() {
992 let provider = ProviderBuilder::new().connect_anvil();
993
994 let url = "https://example.com".to_string();
995 provider.anvil_set_rpc_url(url.clone()).await.unwrap();
996 }
997
998 #[tokio::test]
999 async fn test_anvil_reorg() {
1000 let provider = ProviderBuilder::new().connect_anvil();
1001
1002 provider.anvil_mine(Some(2), None).await.unwrap();
1004
1005 let reorged_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1006 provider.anvil_reorg(ReorgOptions { depth: 1, tx_block_pairs: Vec::new() }).await.unwrap();
1007
1008 let new_block = provider.get_block_by_number(2.into()).await.unwrap().unwrap();
1009
1010 assert_eq!(reorged_block.header.number, new_block.header.number);
1011 assert_ne!(reorged_block.header.hash, new_block.header.hash);
1012 }
1013
1014 #[tokio::test]
1015 #[ignore]
1016 async fn test_anvil_rollback() {
1017 let provider = ProviderBuilder::new().connect_anvil();
1018
1019 provider.anvil_mine(Some(2), None).await.unwrap();
1021
1022 let target_height = provider.get_block_by_number(1.into()).await.unwrap().unwrap();
1023
1024 provider.anvil_rollback(Some(1)).await.unwrap();
1025
1026 let new_head =
1027 provider.get_block_by_number(BlockNumberOrTag::Latest).await.unwrap().unwrap();
1028
1029 assert_eq!(target_height, new_head);
1030 }
1031
1032 #[tokio::test]
1033 async fn test_eth_send_unsigned_transaction() {
1034 let provider = ProviderBuilder::new().connect_anvil();
1035
1036 let alice = Address::random();
1037 let bob = Address::random();
1038 let chain_id = provider.get_chain_id().await.unwrap();
1039
1040 provider.anvil_set_balance(alice, U256::from(1e18 as u64)).await.unwrap();
1041
1042 let tx = TransactionRequest::default()
1043 .with_from(alice)
1044 .with_to(bob)
1045 .with_nonce(0)
1046 .with_chain_id(chain_id)
1047 .with_value(U256::from(100))
1048 .with_gas_limit(21_000)
1049 .with_max_priority_fee_per_gas(1_000_000_000)
1050 .with_max_fee_per_gas(20_000_000_000);
1051
1052 let tx_hash = provider.eth_send_unsigned_transaction(tx).await.unwrap();
1053
1054 provider.evm_mine(None).await.unwrap();
1055
1056 let res = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap();
1057 assert_eq!(res.from, alice);
1058 assert_eq!(res.to, Some(bob));
1059 }
1060
1061 #[tokio::test]
1062 async fn test_anvil_deal_erc20() {
1063 let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1064
1065 let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1066 let user = Address::random();
1067 let amount = U256::from(1e18 as u64);
1068
1069 provider.anvil_deal_erc20(user, dai, amount).await.unwrap();
1070
1071 sol! {
1072 function balanceOf(address owner) view returns (uint256);
1073 }
1074
1075 let balance_of_call = balanceOfCall::new((user,));
1076 let input = balanceOfCall::abi_encode(&balance_of_call);
1077
1078 let result = provider
1079 .call(TransactionRequest::default().with_to(dai).with_input(input))
1080 .await
1081 .unwrap();
1082 let balance = balanceOfCall::abi_decode_returns(&result).unwrap();
1083
1084 assert_eq!(balance, amount);
1085 }
1086
1087 #[tokio::test]
1088 async fn test_anvil_set_erc20_allowance() {
1089 let provider = ProviderBuilder::new().connect_anvil_with_config(|a| a.fork(FORK_URL));
1090
1091 let dai = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
1092 let owner = Address::random();
1093 let spender = Address::random();
1094 let amount = U256::from(1e18 as u64);
1095
1096 provider.anvil_set_erc20_allowance(owner, spender, dai, amount).await.unwrap();
1097
1098 sol! {
1099 function allowance(address owner, address spender) view returns (uint256);
1100 }
1101
1102 let allowance_call = allowanceCall::new((owner, spender));
1103 let input = allowanceCall::abi_encode(&allowance_call);
1104
1105 let result = provider
1106 .call(TransactionRequest::default().with_to(dai).with_input(input))
1107 .await
1108 .unwrap();
1109 let allowance = allowanceCall::abi_decode_returns(&result).unwrap();
1110
1111 assert_eq!(allowance, amount);
1112 }
1113}