@@ -26,27 +26,8 @@ abstract contract StdCheatsSafe {
2626 string rpcUrl;
2727 }
2828
29- struct Chains {
30- Chain Anvil;
31- Chain Hardhat;
32- Chain Mainnet;
33- Chain Goerli;
34- Chain Sepolia;
35- Chain Optimism;
36- Chain OptimismGoerli;
37- Chain ArbitrumOne;
38- Chain ArbitrumOneGoerli;
39- Chain ArbitrumNova;
40- Chain Polygon;
41- Chain PolygonMumbai;
42- Chain Avalanche;
43- Chain AvalancheFuji;
44- Chain BnbSmartChain;
45- Chain BnbSmartChainTestnet;
46- Chain GnosisChain;
47- }
48-
49- Chains stdChains;
29+ // Maps from a chain's name (matching what's in the `foundry.toml` file) to chain data.
30+ mapping (string => Chain) internal stdChains;
5031
5132 // Data structures to parse Transaction objects from the broadcast artifact
5233 // that conform to EIP1559. The Raw structs is what is parsed from the JSON
@@ -227,63 +208,33 @@ abstract contract StdCheatsSafe {
227208
228209 function _constructor () private returns (uint256 ) {
229210 // Initialize `stdChains` with the defaults.
230- stdChains = Chains ({
231- Anvil: Chain ("Anvil " , 31337 , "http://127.0.0.1:8545 " ),
232- Hardhat: Chain ("Hardhat " , 31337 , "http://127.0.0.1:8545 " ),
233- Mainnet: Chain ("Mainnet " , 1 , "https://api.mycryptoapi.com/eth " ),
234- Goerli: Chain ("Goerli " , 5 , "https://goerli.infura.io/v3/84842078b09946638c03157f83405213 " ), // Default Infura key from ethers.js: https://github.com/ethers-io/ethers.js/blob/c80fcddf50a9023486e9f9acb1848aba4c19f7b6/packages/providers/src.ts/infura-provider.ts
235- Sepolia: Chain ("Sepolia " , 11155111 , "https://rpc.sepolia.dev " ),
236- Optimism: Chain ("Optimism " , 10 , "https://mainnet.optimism.io " ),
237- OptimismGoerli: Chain ("OptimismGoerli " , 420 , "https://goerli.optimism.io " ),
238- ArbitrumOne: Chain ("ArbitrumOne " , 42161 , "https://arb1.arbitrum.io/rpc " ),
239- ArbitrumOneGoerli: Chain ("ArbitrumOneGoerli " , 421613 , "https://goerli-rollup.arbitrum.io/rpc " ),
240- ArbitrumNova: Chain ("ArbitrumNova " , 42170 , "https://nova.arbitrum.io/rpc " ),
241- Polygon: Chain ("Polygon " , 137 , "https://polygon-rpc.com " ),
242- PolygonMumbai: Chain ("PolygonMumbai " , 80001 , "https://rpc-mumbai.matic.today " ),
243- Avalanche: Chain ("Avalanche " , 43114 , "https://api.avax.network/ext/bc/C/rpc " ),
244- AvalancheFuji: Chain ("AvalancheFuji " , 43113 , "https://api.avax-test.network/ext/bc/C/rpc " ),
245- BnbSmartChain: Chain ("BnbSmartChain " , 56 , "https://bsc-dataseed1.binance.org " ),
246- BnbSmartChainTestnet: Chain ("BnbSmartChainTestnet " , 97 , "https://data-seed-prebsc-1-s1.binance.org:8545 " ),
247- GnosisChain: Chain ("GnosisChain " , 100 , "https://rpc.gnosischain.com " )
248- });
211+ stdChains["anvil " ] = Chain ("Anvil " , 31337 , "http://127.0.0.1:8545 " );
212+ stdChains["hardhat " ] = Chain ("Hardhat " , 31337 , "http://127.0.0.1:8545 " );
213+ stdChains["mainnet " ] = Chain ("Mainnet " , 1 , "https://api.mycryptoapi.com/eth " );
214+ stdChains["goerli " ] = Chain ("Goerli " , 5 , "https://goerli.infura.io/v3/6770454bc6ea42c58aac12978531b93f " );
215+ stdChains["sepolia " ] = Chain ("Sepolia " , 11155111 , "https://rpc.sepolia.dev " );
216+ stdChains["optimism " ] = Chain ("Optimism " , 10 , "https://mainnet.optimism.io " );
217+ stdChains["optimism_goerli " ] = Chain ("Optimism Goerli " , 420 , "https://goerli.optimism.io " );
218+ stdChains["arbitrum_one " ] = Chain ("Arbitrum One " , 42161 , "https://arb1.arbitrum.io/rpc " );
219+ stdChains["arbitrum_one_goerli " ] = Chain ("Arbitrum One Goerli " , 421613 , "https://goerli-rollup.arbitrum.io/rpc " );
220+ stdChains["arbitrum_nova " ] = Chain ("Arbitrum Nova " , 42170 , "https://nova.arbitrum.io/rpc " );
221+ stdChains["polygon " ] = Chain ("Polygon " , 137 , "https://polygon-rpc.com " );
222+ stdChains["polygon_mumbai " ] = Chain ("Polygon Mumbai " , 80001 , "https://rpc-mumbai.matic.today " );
223+ stdChains["avalanche " ] = Chain ("Avalanche " , 43114 , "https://api.avax.network/ext/bc/C/rpc " );
224+ stdChains["avalanche_fuji " ] = Chain ("Avalanche Fuji " , 43113 , "https://api.avax-test.network/ext/bc/C/rpc " );
225+ stdChains["bnb_smart_chain " ] = Chain ("BNB Smart Chain " , 56 , "https://bsc-dataseed1.binance.org " );
226+ stdChains["bnb_smart_chain_testnet " ] = Chain ("BNB Smart Chain Testnet " , 97 , "https://data-seed-prebsc-1-s1.binance.org:8545 " );// forgefmt: disable-line
227+ stdChains["gnosis_chain " ] = Chain ("Gnosis Chain " , 100 , "https://rpc.gnosischain.com " );
249228
250229 // Loop over RPC URLs in the config file to replace the default RPC URLs
251- ( string [ 2 ][] memory rpcs ) = vm.rpcUrls ();
230+ Vm.Rpc[] memory rpcs = vm.rpcUrlStructs ();
252231 for (uint256 i = 0 ; i < rpcs.length ; i++ ) {
253- (string memory name , string memory rpcUrl ) = (rpcs[i][0 ], rpcs[i][1 ]);
254- // forgefmt: disable-start
255- if (isEqual (name, "anvil " )) stdChains.Anvil.rpcUrl = rpcUrl;
256- else if (isEqual (name, "hardhat " )) stdChains.Hardhat.rpcUrl = rpcUrl;
257- else if (isEqual (name, "mainnet " )) stdChains.Mainnet.rpcUrl = rpcUrl;
258- else if (isEqual (name, "goerli " )) stdChains.Goerli.rpcUrl = rpcUrl;
259- else if (isEqual (name, "sepolia " )) stdChains.Sepolia.rpcUrl = rpcUrl;
260- else if (isEqual (name, "optimism " )) stdChains.Optimism.rpcUrl = rpcUrl;
261- else if (isEqual (name, "optimism_goerli " , "optimism-goerli " )) stdChains.OptimismGoerli.rpcUrl = rpcUrl;
262- else if (isEqual (name, "arbitrum_one " , "arbitrum-one " )) stdChains.ArbitrumOne.rpcUrl = rpcUrl;
263- else if (isEqual (name, "arbitrum_one_goerli " , "arbitrum-one-goerli " )) stdChains.ArbitrumOneGoerli.rpcUrl = rpcUrl;
264- else if (isEqual (name, "arbitrum_nova " , "arbitrum-nova " )) stdChains.ArbitrumNova.rpcUrl = rpcUrl;
265- else if (isEqual (name, "polygon " )) stdChains.Polygon.rpcUrl = rpcUrl;
266- else if (isEqual (name, "polygon_mumbai " , "polygon-mumbai " )) stdChains.PolygonMumbai.rpcUrl = rpcUrl;
267- else if (isEqual (name, "avalanche " )) stdChains.Avalanche.rpcUrl = rpcUrl;
268- else if (isEqual (name, "avalanche_fuji " , "avalanche-fuji " )) stdChains.AvalancheFuji.rpcUrl = rpcUrl;
269- else if (isEqual (name, "bnb_smart_chain " , "bnb-smart-chain " )) stdChains.BnbSmartChain.rpcUrl = rpcUrl;
270- else if (isEqual (name, "bnb_smart_chain_testnet " , "bnb-smart-chain-testnet " )) stdChains.BnbSmartChainTestnet.rpcUrl = rpcUrl;
271- else if (isEqual (name, "gnosis_chain " , "gnosis-chain " )) stdChains.GnosisChain.rpcUrl = rpcUrl;
272- // forgefmt: disable-end
232+ stdChains[rpcs[i].name].rpcUrl = rpcs[i].url;
273233 }
274234 return 0 ;
275235 }
276236
277- function isEqual (string memory a , string memory b ) private pure returns (bool ) {
278- return keccak256 (abi.encode (a)) == keccak256 (abi.encode (b));
279- }
280-
281- function isEqual (string memory a , string memory b , string memory c ) private pure returns (bool ) {
282- return
283- keccak256 (abi.encode (a)) == keccak256 (abi.encode (b)) || keccak256 (abi.encode (a)) == keccak256 (abi.encode (c));
284- }
285-
286- function assumeNoPrecompiles (address addr ) internal virtual {
237+ function assumeNoPrecompiles (address addr ) internal view virtual {
287238 // Assembly required since `block.chainid` was introduced in 0.8.0.
288239 uint256 chainId;
289240 assembly {
@@ -292,21 +243,21 @@ abstract contract StdCheatsSafe {
292243 assumeNoPrecompiles (addr, chainId);
293244 }
294245
295- function assumeNoPrecompiles (address addr , uint256 chainId ) internal virtual {
246+ function assumeNoPrecompiles (address addr , uint256 chainId ) internal view virtual {
296247 // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific
297248 // address), but the same rationale for excluding them applies so we include those too.
298249
299250 // These should be present on all EVM-compatible chains.
300251 vm.assume (addr < address (0x1 ) || addr > address (0x9 ));
301252
302253 // forgefmt: disable-start
303- if (chainId == stdChains.Optimism. chainId || chainId == stdChains.OptimismGoerli .chainId) {
254+ if (chainId == stdChains[ " optimism " ]. chainId || chainId == stdChains[ " optimism_goerli " ] .chainId) {
304255 // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21
305256 vm.assume (addr < address (0x4200000000000000000000000000000000000000 ) || addr > address (0x4200000000000000000000000000000000000800 ));
306- } else if (chainId == stdChains.ArbitrumOne. chainId || chainId == stdChains.ArbitrumOneGoerli .chainId) {
257+ } else if (chainId == stdChains[ " arbitrum_one " ]. chainId || chainId == stdChains[ " arbitrum_one_goerli " ] .chainId) {
307258 // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains
308259 vm.assume (addr < address (0x0000000000000000000000000000000000000064 ) || addr > address (0x0000000000000000000000000000000000000068 ));
309- } else if (chainId == stdChains.Avalanche. chainId || chainId == stdChains.AvalancheFuji .chainId) {
260+ } else if (chainId == stdChains[ " avalanche " ]. chainId || chainId == stdChains[ " avalanche_fuji " ] .chainId) {
310261 // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59
311262 vm.assume (addr < address (0x0100000000000000000000000000000000000000 ) || addr > address (0x01000000000000000000000000000000000000ff ));
312263 vm.assume (addr < address (0x0200000000000000000000000000000000000000 ) || addr > address (0x02000000000000000000000000000000000000FF ));
@@ -315,7 +266,12 @@ abstract contract StdCheatsSafe {
315266 // forgefmt: disable-end
316267 }
317268
318- function readEIP1559ScriptArtifact (string memory path ) internal virtual returns (EIP1559ScriptArtifact memory ) {
269+ function readEIP1559ScriptArtifact (string memory path )
270+ internal
271+ view
272+ virtual
273+ returns (EIP1559ScriptArtifact memory )
274+ {
319275 string memory data = vm.readFile (path);
320276 bytes memory parsedData = vm.parseJson (data);
321277 RawEIP1559ScriptArtifact memory rawArtifact = abi.decode (parsedData, (RawEIP1559ScriptArtifact));
@@ -367,14 +323,14 @@ abstract contract StdCheatsSafe {
367323 return txDetail;
368324 }
369325
370- function readTx1559s (string memory path ) internal virtual returns (Tx1559[] memory ) {
326+ function readTx1559s (string memory path ) internal view virtual returns (Tx1559[] memory ) {
371327 string memory deployData = vm.readFile (path);
372328 bytes memory parsedDeployData = vm.parseJson (deployData, ".transactions " );
373329 RawTx1559[] memory rawTxs = abi.decode (parsedDeployData, (RawTx1559[]));
374330 return rawToConvertedEIPTx1559s (rawTxs);
375331 }
376332
377- function readTx1559 (string memory path , uint256 index ) internal virtual returns (Tx1559 memory ) {
333+ function readTx1559 (string memory path , uint256 index ) internal view virtual returns (Tx1559 memory ) {
378334 string memory deployData = vm.readFile (path);
379335 string memory key = string (abi.encodePacked (".transactions[ " , vm.toString (index), "] " ));
380336 bytes memory parsedDeployData = vm.parseJson (deployData, key);
@@ -383,14 +339,14 @@ abstract contract StdCheatsSafe {
383339 }
384340
385341 // Analogous to readTransactions, but for receipts.
386- function readReceipts (string memory path ) internal virtual returns (Receipt[] memory ) {
342+ function readReceipts (string memory path ) internal view virtual returns (Receipt[] memory ) {
387343 string memory deployData = vm.readFile (path);
388344 bytes memory parsedDeployData = vm.parseJson (deployData, ".receipts " );
389345 RawReceipt[] memory rawReceipts = abi.decode (parsedDeployData, (RawReceipt[]));
390346 return rawToConvertedReceipts (rawReceipts);
391347 }
392348
393- function readReceipt (string memory path , uint256 index ) internal virtual returns (Receipt memory ) {
349+ function readReceipt (string memory path , uint256 index ) internal view virtual returns (Receipt memory ) {
394350 string memory deployData = vm.readFile (path);
395351 string memory key = string (abi.encodePacked (".receipts[ " , vm.toString (index), "] " ));
396352 bytes memory parsedDeployData = vm.parseJson (deployData, key);
0 commit comments