# Anvil Advanced Usage Advanced Anvil features for local development and testing. ## Account Impersonation ### Auto-Impersonate All Accounts ```bash # Start with auto-impersonation anvil --auto-impersonate ``` Now any account can send transactions without private key: ```bash cast send $CONTRACT "transfer(address,uint256)" $TO 1000 \ --from 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 \ --unlocked ``` ### Impersonate Specific Account ```bash # Via RPC cast rpc anvil_impersonateAccount 0x1234... # Stop impersonating cast rpc anvil_stopImpersonatingAccount 0x1234... ``` ### In Foundry Tests ```solidity address whale = 0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503; vm.startPrank(whale); usdc.transfer(address(this), 1_000_000e6); vm.stopPrank(); ``` ## State Manipulation ### Set Balance ```bash # Set ETH balance cast rpc anvil_setBalance 0x1234... 0xDE0B6B3A7640000 # 1 ETH in hex # In tests vm.deal(address, 100 ether); ``` ### Set Code ```bash # Deploy code at address cast rpc anvil_setCode 0x1234... 0x608060405234801... # In tests vm.etch(address, code); ``` ### Set Storage ```bash # Set storage slot cast rpc anvil_setStorageAt 0x1234... 0x0 0x... # In tests vm.store(address, slot, value); ``` ### Set Nonce ```bash cast rpc anvil_setNonce 0x1234... 0x10 # 16 in hex ``` ## Mining Modes ### Auto-Mining (Default) ```bash anvil # Mines block on each transaction ``` ### Interval Mining ```bash # Mine every 12 seconds anvil --block-time 12 ``` ### Manual Mining ```bash # Disable auto-mining anvil --no-mining # Mine manually cast rpc evm_mine # Mine multiple blocks cast rpc anvil_mine 10 # Mine 10 blocks ``` ### Mining Control ```bash # Enable auto-mine cast rpc evm_setAutomine true # Set interval cast rpc evm_setIntervalMining 5000 # 5 seconds in ms ``` ## State Snapshots ### Dump State ```bash # Start anvil, make changes, then dump anvil --dump-state state.json # Load from previous state anvil --load-state state.json ``` ### Runtime Snapshots ```bash # Create snapshot SNAPSHOT_ID=$(cast rpc evm_snapshot) # Make changes... # Revert to snapshot cast rpc evm_revert $SNAPSHOT_ID ``` ### In Tests ```solidity uint256 snapshot = vm.snapshot(); // Make changes... vm.revertTo(snapshot); ``` ## Fork Configuration ### Basic Fork ```bash anvil --fork-url https://eth-mainnet.g.alchemy.com/v2/KEY ``` ### Pin Block ```bash anvil --fork-url $RPC_URL --fork-block-number 18000000 ``` ### Fork with Caching ```bash # Cache fork data locally anvil --fork-url $RPC_URL --fork-retry-backoff 1000 # Disable caching anvil --fork-url $RPC_URL --no-storage-caching ``` ### Multiple Forks ```solidity // In tests uint256 mainnetFork = vm.createFork("mainnet"); uint256 arbitrumFork = vm.createFork("arbitrum"); vm.selectFork(mainnetFork); // Test on mainnet... vm.selectFork(arbitrumFork); // Test on arbitrum... ``` ## Time Manipulation ```bash # Set timestamp cast rpc evm_setNextBlockTimestamp 1700000000 # Increase time cast rpc evm_increaseTime 86400 # 1 day # In tests vm.warp(block.timestamp + 1 days); vm.roll(block.number + 100); ``` ## RPC Methods ### Common Anvil RPC | Method | Description | |--------|-------------| | `anvil_setBalance` | Set ETH balance | | `anvil_setCode` | Set contract code | | `anvil_setStorageAt` | Set storage slot | | `anvil_setNonce` | Set account nonce | | `anvil_impersonateAccount` | Impersonate address | | `anvil_mine` | Mine blocks | | `anvil_reset` | Reset fork | | `anvil_dumpState` | Export state | | `anvil_loadState` | Import state | ### EVM Methods | Method | Description | |--------|-------------| | `evm_snapshot` | Create snapshot | | `evm_revert` | Revert to snapshot | | `evm_mine` | Mine single block | | `evm_setAutomine` | Toggle auto-mining | | `evm_increaseTime` | Advance time | | `evm_setNextBlockTimestamp` | Set next timestamp | ## Configuration ### Startup Options ```bash anvil \ --port 8545 \ --accounts 10 \ --balance 10000 \ --mnemonic "test test test..." \ --derivation-path "m/44'/60'/0'/0/" \ --block-time 12 \ --gas-limit 30000000 \ --gas-price 0 \ --chain-id 31337 \ --hardfork prague ``` ### Hardfork Selection ```bash anvil --hardfork shanghai anvil --hardfork cancun anvil --hardfork prague # Latest ``` ## Testing Patterns ### Fork Test Setup ```solidity function setUp() public { vm.createSelectFork(vm.envString("MAINNET_RPC_URL"), 18000000); // Impersonate whale address whale = 0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503; vm.startPrank(whale); usdc.transfer(address(this), 1_000_000e6); vm.stopPrank(); } ``` ### State Reset Between Tests ```solidity uint256 snapshot; function setUp() public { if (snapshot == 0) { // First run: setup and snapshot _deployContracts(); snapshot = vm.snapshot(); } else { // Subsequent runs: revert to clean state vm.revertTo(snapshot); } } ``` ### Testing Mainnet Interactions ```solidity function test_SwapOnUniswap() public { vm.createSelectFork("mainnet"); address router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; address weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; deal(address(this), 10 ether); IRouter(router).swapExactETHForTokens{value: 1 ether}( 0, path, address(this), block.timestamp ); } ```