@godzillaba/mutest 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/.devcontainer/Dockerfile +117 -0
  2. package/.devcontainer/devcontainer.json +62 -0
  3. package/.devcontainer/init-firewall.sh +118 -0
  4. package/.github/workflows/test.yml +38 -0
  5. package/.gitmodules +3 -0
  6. package/CLAUDE.md +39 -0
  7. package/README.md +33 -0
  8. package/foundry.lock +8 -0
  9. package/foundry.toml +6 -0
  10. package/index.ts +97 -0
  11. package/lib/forge-std/.gitattributes +1 -0
  12. package/lib/forge-std/.github/CODEOWNERS +1 -0
  13. package/lib/forge-std/.github/dependabot.yml +6 -0
  14. package/lib/forge-std/.github/workflows/ci.yml +125 -0
  15. package/lib/forge-std/.github/workflows/sync.yml +36 -0
  16. package/lib/forge-std/CONTRIBUTING.md +193 -0
  17. package/lib/forge-std/LICENSE-APACHE +203 -0
  18. package/lib/forge-std/LICENSE-MIT +25 -0
  19. package/lib/forge-std/README.md +314 -0
  20. package/lib/forge-std/RELEASE_CHECKLIST.md +12 -0
  21. package/lib/forge-std/foundry.toml +18 -0
  22. package/lib/forge-std/package.json +16 -0
  23. package/lib/forge-std/scripts/vm.py +636 -0
  24. package/lib/forge-std/src/Base.sol +48 -0
  25. package/lib/forge-std/src/Config.sol +60 -0
  26. package/lib/forge-std/src/LibVariable.sol +477 -0
  27. package/lib/forge-std/src/Script.sol +28 -0
  28. package/lib/forge-std/src/StdAssertions.sol +779 -0
  29. package/lib/forge-std/src/StdChains.sol +303 -0
  30. package/lib/forge-std/src/StdCheats.sol +825 -0
  31. package/lib/forge-std/src/StdConfig.sol +632 -0
  32. package/lib/forge-std/src/StdConstants.sol +30 -0
  33. package/lib/forge-std/src/StdError.sol +15 -0
  34. package/lib/forge-std/src/StdInvariant.sol +140 -0
  35. package/lib/forge-std/src/StdJson.sol +275 -0
  36. package/lib/forge-std/src/StdMath.sol +47 -0
  37. package/lib/forge-std/src/StdStorage.sol +475 -0
  38. package/lib/forge-std/src/StdStyle.sol +333 -0
  39. package/lib/forge-std/src/StdToml.sol +275 -0
  40. package/lib/forge-std/src/StdUtils.sol +200 -0
  41. package/lib/forge-std/src/Test.sol +32 -0
  42. package/lib/forge-std/src/Vm.sol +2533 -0
  43. package/lib/forge-std/src/console.sol +1551 -0
  44. package/lib/forge-std/src/console2.sol +4 -0
  45. package/lib/forge-std/src/interfaces/IERC1155.sol +105 -0
  46. package/lib/forge-std/src/interfaces/IERC165.sol +12 -0
  47. package/lib/forge-std/src/interfaces/IERC20.sol +43 -0
  48. package/lib/forge-std/src/interfaces/IERC4626.sol +190 -0
  49. package/lib/forge-std/src/interfaces/IERC6909.sol +72 -0
  50. package/lib/forge-std/src/interfaces/IERC721.sol +164 -0
  51. package/lib/forge-std/src/interfaces/IERC7540.sol +144 -0
  52. package/lib/forge-std/src/interfaces/IERC7575.sol +241 -0
  53. package/lib/forge-std/src/interfaces/IMulticall3.sol +68 -0
  54. package/lib/forge-std/src/safeconsole.sol +13248 -0
  55. package/lib/forge-std/test/CommonBase.t.sol +44 -0
  56. package/lib/forge-std/test/Config.t.sol +381 -0
  57. package/lib/forge-std/test/LibVariable.t.sol +452 -0
  58. package/lib/forge-std/test/StdAssertions.t.sol +141 -0
  59. package/lib/forge-std/test/StdChains.t.sol +227 -0
  60. package/lib/forge-std/test/StdCheats.t.sol +638 -0
  61. package/lib/forge-std/test/StdConstants.t.sol +38 -0
  62. package/lib/forge-std/test/StdError.t.sol +119 -0
  63. package/lib/forge-std/test/StdJson.t.sol +49 -0
  64. package/lib/forge-std/test/StdMath.t.sol +202 -0
  65. package/lib/forge-std/test/StdStorage.t.sol +485 -0
  66. package/lib/forge-std/test/StdStyle.t.sol +110 -0
  67. package/lib/forge-std/test/StdToml.t.sol +49 -0
  68. package/lib/forge-std/test/StdUtils.t.sol +342 -0
  69. package/lib/forge-std/test/Vm.t.sol +18 -0
  70. package/lib/forge-std/test/compilation/CompilationScript.sol +8 -0
  71. package/lib/forge-std/test/compilation/CompilationScriptBase.sol +8 -0
  72. package/lib/forge-std/test/compilation/CompilationTest.sol +8 -0
  73. package/lib/forge-std/test/compilation/CompilationTestBase.sol +8 -0
  74. package/lib/forge-std/test/fixtures/broadcast.log.json +187 -0
  75. package/lib/forge-std/test/fixtures/config.toml +81 -0
  76. package/lib/forge-std/test/fixtures/test.json +8 -0
  77. package/lib/forge-std/test/fixtures/test.toml +6 -0
  78. package/package.json +10 -0
  79. package/script/Counter.s.sol +19 -0
  80. package/src/Counter.sol +14 -0
  81. package/test/Counter.t.sol +24 -0
@@ -0,0 +1,44 @@
1
+ // SPDX-License-Identifier: MIT OR Apache-2.0
2
+ pragma solidity >=0.8.13 <0.9.0;
3
+
4
+ import {CommonBase} from "../src/Base.sol";
5
+ import {StdConstants} from "../src/StdConstants.sol";
6
+ import {Test} from "../src/Test.sol";
7
+
8
+ contract CommonBaseTest is Test {
9
+ function testVmAddressValue() public pure {
10
+ assertEq(VM_ADDRESS, address(StdConstants.VM));
11
+ }
12
+
13
+ function testConsoleValue() public pure {
14
+ assertEq(CONSOLE, StdConstants.CONSOLE);
15
+ }
16
+
17
+ function testCreate2FactoryValue() public pure {
18
+ assertEq(CREATE2_FACTORY, StdConstants.CREATE2_FACTORY);
19
+ }
20
+
21
+ function testDefaultSenderValue() public pure {
22
+ assertEq(DEFAULT_SENDER, StdConstants.DEFAULT_SENDER);
23
+ }
24
+
25
+ function testDefaultTestContractValue() public pure {
26
+ assertEq(DEFAULT_TEST_CONTRACT, StdConstants.DEFAULT_TEST_CONTRACT);
27
+ }
28
+
29
+ function testMulticall3AddressValue() public pure {
30
+ assertEq(MULTICALL3_ADDRESS, address(StdConstants.MULTICALL3_ADDRESS));
31
+ }
32
+
33
+ function testSecp256k1OrderValue() public pure {
34
+ assertEq(SECP256K1_ORDER, StdConstants.SECP256K1_ORDER);
35
+ }
36
+
37
+ function testUint256MaxValue() public pure {
38
+ assertEq(UINT256_MAX, type(uint256).max);
39
+ }
40
+
41
+ function testVmValue() public pure {
42
+ assertEq(address(vm), address(StdConstants.VM));
43
+ }
44
+ }
@@ -0,0 +1,381 @@
1
+ // SPDX-License-Identifier: MIT OR Apache-2.0
2
+ pragma solidity ^0.8.13;
3
+
4
+ import {Test} from "../src/Test.sol";
5
+ import {Config} from "../src/Config.sol";
6
+ import {StdConfig} from "../src/StdConfig.sol";
7
+
8
+ contract ConfigTest is Test, Config {
9
+ function setUp() public {
10
+ vm.setEnv("MAINNET_RPC", "https://ethereum.reth.rs/rpc");
11
+ vm.setEnv("WETH_MAINNET", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2");
12
+ vm.setEnv("OPTIMISM_RPC", "https://mainnet.optimism.io");
13
+ vm.setEnv("WETH_OPTIMISM", "0x4200000000000000000000000000000000000006");
14
+ }
15
+
16
+ function test_loadConfig() public {
17
+ // Deploy the config contract with the test fixture.
18
+ _loadConfig("./test/fixtures/config.toml", false);
19
+
20
+ // -- MAINNET --------------------------------------------------------------
21
+
22
+ // Read and assert RPC URL for Mainnet (chain ID 1)
23
+ assertEq(config.getRpcUrl(1), "https://ethereum.reth.rs/rpc");
24
+
25
+ // Read and assert boolean values
26
+ assertTrue(config.get(1, "is_live").toBool());
27
+ bool[] memory bool_array = config.get(1, "bool_array").toBoolArray();
28
+ assertTrue(bool_array[0]);
29
+ assertFalse(bool_array[1]);
30
+
31
+ // Read and assert address values
32
+ assertEq(config.get(1, "weth").toAddress(), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
33
+ address[] memory address_array = config.get(1, "deps").toAddressArray();
34
+ assertEq(address_array[0], 0x0000000000000000000000000000000000000000);
35
+ assertEq(address_array[1], 0x1111111111111111111111111111111111111111);
36
+
37
+ // Read and assert bytes32 values
38
+ assertEq(config.get(1, "word").toBytes32(), bytes32(uint256(1234)));
39
+ bytes32[] memory bytes32_array = config.get(1, "word_array").toBytes32Array();
40
+ assertEq(bytes32_array[0], bytes32(uint256(5678)));
41
+ assertEq(bytes32_array[1], bytes32(uint256(9999)));
42
+
43
+ // Read and assert uint values
44
+ assertEq(config.get(1, "number").toUint256(), 1234);
45
+ uint256[] memory uint_array = config.get(1, "number_array").toUint256Array();
46
+ assertEq(uint_array[0], 5678);
47
+ assertEq(uint_array[1], 9999);
48
+
49
+ // Read and assert int values
50
+ assertEq(config.get(1, "signed_number").toInt256(), -1234);
51
+ int256[] memory int_array = config.get(1, "signed_number_array").toInt256Array();
52
+ assertEq(int_array[0], -5678);
53
+ assertEq(int_array[1], 9999);
54
+
55
+ // Read and assert bytes values
56
+ assertEq(config.get(1, "b").toBytes(), hex"abcd");
57
+ bytes[] memory bytes_array = config.get(1, "b_array").toBytesArray();
58
+ assertEq(bytes_array[0], hex"dead");
59
+ assertEq(bytes_array[1], hex"beef");
60
+
61
+ // Read and assert string values
62
+ assertEq(config.get(1, "str").toString(), "foo");
63
+ string[] memory string_array = config.get(1, "str_array").toStringArray();
64
+ assertEq(string_array[0], "bar");
65
+ assertEq(string_array[1], "baz");
66
+
67
+ // -- OPTIMISM ------------------------------------------------------------
68
+
69
+ // Read and assert RPC URL for Optimism (chain ID 10)
70
+ assertEq(config.getRpcUrl(10), "https://mainnet.optimism.io");
71
+
72
+ // Read and assert boolean values
73
+ assertFalse(config.get(10, "is_live").toBool());
74
+ bool_array = config.get(10, "bool_array").toBoolArray();
75
+ assertFalse(bool_array[0]);
76
+ assertTrue(bool_array[1]);
77
+
78
+ // Read and assert address values
79
+ assertEq(config.get(10, "weth").toAddress(), 0x4200000000000000000000000000000000000006);
80
+ address_array = config.get(10, "deps").toAddressArray();
81
+ assertEq(address_array[0], 0x2222222222222222222222222222222222222222);
82
+ assertEq(address_array[1], 0x3333333333333333333333333333333333333333);
83
+
84
+ // Read and assert bytes32 values
85
+ assertEq(config.get(10, "word").toBytes32(), bytes32(uint256(9999)));
86
+ bytes32_array = config.get(10, "word_array").toBytes32Array();
87
+ assertEq(bytes32_array[0], bytes32(uint256(1234)));
88
+ assertEq(bytes32_array[1], bytes32(uint256(5678)));
89
+
90
+ // Read and assert uint values
91
+ assertEq(config.get(10, "number").toUint256(), 9999);
92
+ uint_array = config.get(10, "number_array").toUint256Array();
93
+ assertEq(uint_array[0], 1234);
94
+ assertEq(uint_array[1], 5678);
95
+
96
+ // Read and assert int values
97
+ assertEq(config.get(10, "signed_number").toInt256(), 9999);
98
+ int_array = config.get(10, "signed_number_array").toInt256Array();
99
+ assertEq(int_array[0], -1234);
100
+ assertEq(int_array[1], -5678);
101
+
102
+ // Read and assert bytes values
103
+ assertEq(config.get(10, "b").toBytes(), hex"dcba");
104
+ bytes_array = config.get(10, "b_array").toBytesArray();
105
+ assertEq(bytes_array[0], hex"c0ffee");
106
+ assertEq(bytes_array[1], hex"babe");
107
+
108
+ // Read and assert string values
109
+ assertEq(config.get(10, "str").toString(), "alice");
110
+ string_array = config.get(10, "str_array").toStringArray();
111
+ assertEq(string_array[0], "bob");
112
+ assertEq(string_array[1], "charlie");
113
+ }
114
+
115
+ function test_loadConfigAndForks() public {
116
+ _loadConfigAndForks("./test/fixtures/config.toml", false);
117
+
118
+ // assert that the map of chain id and fork ids is created and that the chain ids actually match
119
+ assertEq(forkOf[1], 0);
120
+ vm.selectFork(forkOf[1]);
121
+ assertEq(vm.getChainId(), 1);
122
+
123
+ assertEq(forkOf[10], 1);
124
+ vm.selectFork(forkOf[10]);
125
+ assertEq(vm.getChainId(), 10);
126
+ }
127
+
128
+ function test_configExists() public {
129
+ _loadConfig("./test/fixtures/config.toml", false);
130
+
131
+ string[] memory keys = new string[](7);
132
+ keys[0] = "is_live";
133
+ keys[1] = "weth";
134
+ keys[2] = "word";
135
+ keys[3] = "number";
136
+ keys[4] = "signed_number";
137
+ keys[5] = "b";
138
+ keys[6] = "str";
139
+
140
+ // Read and assert RPC URL for Mainnet (chain ID 1)
141
+ assertEq(config.getRpcUrl(1), "https://ethereum.reth.rs/rpc");
142
+
143
+ for (uint256 i = 0; i < keys.length; ++i) {
144
+ assertTrue(config.exists(1, keys[i]));
145
+ assertFalse(config.exists(1, string.concat(keys[i], "_")));
146
+ }
147
+
148
+ // Assert RPC URL for Optimism (chain ID 10)
149
+ assertEq(config.getRpcUrl(10), "https://mainnet.optimism.io");
150
+
151
+ for (uint256 i = 0; i < keys.length; ++i) {
152
+ assertTrue(config.exists(10, keys[i]));
153
+ assertFalse(config.exists(10, string.concat(keys[i], "_")));
154
+ }
155
+ }
156
+
157
+ function test_writeConfig() public {
158
+ // Create a temporary copy of the config file to avoid modifying the original.
159
+ string memory originalConfig = "./test/fixtures/config.toml";
160
+ string memory testConfig = "./test/fixtures/config.t.toml";
161
+ vm.copyFile(originalConfig, testConfig);
162
+
163
+ // Deploy the config contract with the temporary fixture.
164
+ _loadConfig(testConfig, false);
165
+
166
+ // Enable writing to file bypassing the context check.
167
+ vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1)));
168
+
169
+ {
170
+ // Update a single boolean value and verify the change.
171
+ config.set(1, "is_live", false);
172
+
173
+ assertFalse(config.get(1, "is_live").toBool());
174
+
175
+ string memory content = vm.readFile(testConfig);
176
+ assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live"));
177
+
178
+ // Update a single address value and verify the change.
179
+ address new_addr = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF;
180
+ config.set(1, "weth", new_addr);
181
+
182
+ assertEq(config.get(1, "weth").toAddress(), new_addr);
183
+
184
+ content = vm.readFile(testConfig);
185
+ assertEq(vm.parseTomlAddress(content, "$.mainnet.address.weth"), new_addr);
186
+
187
+ // Update a uint array and verify the change.
188
+ uint256[] memory new_numbers = new uint256[](3);
189
+ new_numbers[0] = 1;
190
+ new_numbers[1] = 2;
191
+ new_numbers[2] = 3;
192
+ config.set(10, "number_array", new_numbers);
193
+
194
+ uint256[] memory updated_numbers_mem = config.get(10, "number_array").toUint256Array();
195
+ assertEq(updated_numbers_mem.length, 3);
196
+ assertEq(updated_numbers_mem[0], 1);
197
+ assertEq(updated_numbers_mem[1], 2);
198
+ assertEq(updated_numbers_mem[2], 3);
199
+
200
+ content = vm.readFile(testConfig);
201
+ uint256[] memory updated_numbers_disk = vm.parseTomlUintArray(content, "$.optimism.uint.number_array");
202
+ assertEq(updated_numbers_disk.length, 3);
203
+ assertEq(updated_numbers_disk[0], 1);
204
+ assertEq(updated_numbers_disk[1], 2);
205
+ assertEq(updated_numbers_disk[2], 3);
206
+
207
+ // Update a string array and verify the change.
208
+ string[] memory new_strings = new string[](2);
209
+ new_strings[0] = "hello";
210
+ new_strings[1] = "world";
211
+ config.set(1, "str_array", new_strings);
212
+
213
+ string[] memory updated_strings_mem = config.get(1, "str_array").toStringArray();
214
+ assertEq(updated_strings_mem.length, 2);
215
+ assertEq(updated_strings_mem[0], "hello");
216
+ assertEq(updated_strings_mem[1], "world");
217
+
218
+ content = vm.readFile(testConfig);
219
+ string[] memory updated_strings_disk = vm.parseTomlStringArray(content, "$.mainnet.string.str_array");
220
+ assertEq(updated_strings_disk.length, 2);
221
+ assertEq(updated_strings_disk[0], "hello");
222
+ assertEq(updated_strings_disk[1], "world");
223
+
224
+ // Create a new uint variable and verify the change.
225
+ config.set(1, "new_uint", uint256(42));
226
+
227
+ assertEq(config.get(1, "new_uint").toUint256(), 42);
228
+
229
+ content = vm.readFile(testConfig);
230
+ assertEq(vm.parseTomlUint(content, "$.mainnet.uint.new_uint"), 42);
231
+
232
+ // Create a new int variable and verify the change.
233
+ config.set(1, "new_int", int256(-42));
234
+
235
+ assertEq(config.get(1, "new_int").toInt256(), -42);
236
+
237
+ content = vm.readFile(testConfig);
238
+ assertEq(vm.parseTomlInt(content, "$.mainnet.int.new_int"), -42);
239
+
240
+ // Create a new int array and verify the change.
241
+ int256[] memory new_ints = new int256[](2);
242
+ new_ints[0] = -100;
243
+ new_ints[1] = 200;
244
+ config.set(10, "new_ints", new_ints);
245
+
246
+ int256[] memory updated_ints_mem = config.get(10, "new_ints").toInt256Array();
247
+ assertEq(updated_ints_mem.length, 2);
248
+ assertEq(updated_ints_mem[0], -100);
249
+ assertEq(updated_ints_mem[1], 200);
250
+
251
+ content = vm.readFile(testConfig);
252
+ int256[] memory updated_ints_disk = vm.parseTomlIntArray(content, "$.optimism.int.new_ints");
253
+ assertEq(updated_ints_disk.length, 2);
254
+ assertEq(updated_ints_disk[0], -100);
255
+ assertEq(updated_ints_disk[1], 200);
256
+
257
+ // Create a new bytes32 array and verify the change.
258
+ bytes32[] memory new_words = new bytes32[](2);
259
+ new_words[0] = bytes32(uint256(0xDEAD));
260
+ new_words[1] = bytes32(uint256(0xBEEF));
261
+ config.set(10, "new_words", new_words);
262
+
263
+ bytes32[] memory updated_words_mem = config.get(10, "new_words").toBytes32Array();
264
+ assertEq(updated_words_mem.length, 2);
265
+ assertEq(updated_words_mem[0], new_words[0]);
266
+ assertEq(updated_words_mem[1], new_words[1]);
267
+
268
+ content = vm.readFile(testConfig);
269
+ bytes32[] memory updated_words_disk = vm.parseTomlBytes32Array(content, "$.optimism.bytes32.new_words");
270
+ assertEq(updated_words_disk.length, 2);
271
+ assertEq(vm.toString(updated_words_disk[0]), vm.toString(new_words[0]));
272
+ assertEq(vm.toString(updated_words_disk[1]), vm.toString(new_words[1]));
273
+ }
274
+
275
+ // Clean up the temporary file.
276
+ vm.removeFile(testConfig);
277
+ }
278
+
279
+ function test_writeUpdatesBackToFile() public {
280
+ // Create a temporary copy of the config file to avoid modifying the original.
281
+ string memory originalConfig = "./test/fixtures/config.toml";
282
+ string memory testConfig = "./test/fixtures/write_config.t.toml";
283
+ vm.copyFile(originalConfig, testConfig);
284
+
285
+ // Deploy the config contract with `writeToFile = false` (disabled).
286
+ _loadConfig(testConfig, false);
287
+
288
+ // Update a single boolean value and verify the file is NOT changed.
289
+ config.set(1, "is_live", false);
290
+ string memory content = vm.readFile(testConfig);
291
+ assertTrue(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should not be updated yet");
292
+
293
+ // Enable writing to file bypassing the context check.
294
+ vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1)));
295
+
296
+ // Update the value again and verify the file IS changed.
297
+ config.set(1, "is_live", false);
298
+ content = vm.readFile(testConfig);
299
+ assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should be updated now");
300
+
301
+ // Disable writing to file.
302
+ config.writeUpdatesBackToFile(false);
303
+
304
+ // Update the value again and verify the file is NOT changed.
305
+ config.set(1, "is_live", true);
306
+ content = vm.readFile(testConfig);
307
+ assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should not be updated again");
308
+
309
+ // Clean up the temporary file.
310
+ vm.removeFile(testConfig);
311
+ }
312
+
313
+ function testRevert_WriteToFileInForbiddenCtxt() public {
314
+ // Cannot initialize enabling writing to file unless we are in SCRIPT mode.
315
+ vm.expectRevert(StdConfig.WriteToFileInForbiddenCtxt.selector);
316
+ _loadConfig("./test/fixtures/config.toml", true);
317
+
318
+ // Initialize with `writeToFile = false`.
319
+ _loadConfig("./test/fixtures/config.toml", false);
320
+
321
+ // Cannot enable writing to file unless we are in SCRIPT mode.
322
+ vm.expectRevert(StdConfig.WriteToFileInForbiddenCtxt.selector);
323
+ config.writeUpdatesBackToFile(true);
324
+ }
325
+
326
+ function testRevert_InvalidChainKey() public {
327
+ // Create a fixture with an invalid chain key
328
+ string memory invalidChainConfig = "./test/fixtures/config_invalid_chain.toml";
329
+ vm.writeFile(
330
+ invalidChainConfig,
331
+ string.concat(
332
+ "[mainnet]\n",
333
+ "endpoint_url = \"https://ethereum.reth.rs/rpc\"\n",
334
+ "\n",
335
+ "[mainnet.uint]\n",
336
+ "valid_number = 123\n",
337
+ "\n",
338
+ "# Invalid chain key (not a number and not a valid alias)\n",
339
+ "[invalid_chain]\n",
340
+ "endpoint_url = \"https://invalid.com\"\n",
341
+ "\n",
342
+ "[invalid_chain_9999.uint]\n",
343
+ "some_value = 456\n"
344
+ )
345
+ );
346
+
347
+ vm.expectRevert(abi.encodeWithSelector(StdConfig.InvalidChainKey.selector, "invalid_chain"));
348
+ new StdConfig(invalidChainConfig, false);
349
+ vm.removeFile(invalidChainConfig);
350
+ }
351
+
352
+ function testRevert_ChainNotInitialized() public {
353
+ _loadConfig("./test/fixtures/config.toml", false);
354
+
355
+ // Enable writing to file bypassing the context check.
356
+ vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1)));
357
+
358
+ // Try to write a value for a non-existent chain ID
359
+ vm.expectRevert(abi.encodeWithSelector(StdConfig.ChainNotInitialized.selector, uint256(999999)));
360
+ config.set(999999, "some_key", uint256(123));
361
+ }
362
+
363
+ function testRevert_UnableToParseVariable() public {
364
+ // Create a temporary fixture with an unparsable variable
365
+ string memory badParseConfig = "./test/fixtures/config_bad_parse.toml";
366
+ vm.writeFile(
367
+ badParseConfig,
368
+ string.concat(
369
+ "[mainnet]\n",
370
+ "endpoint_url = \"https://ethereum.reth.rs/rpc\"\n",
371
+ "\n",
372
+ "[mainnet.uint]\n",
373
+ "bad_value = \"not_a_number\"\n"
374
+ )
375
+ );
376
+
377
+ vm.expectRevert(abi.encodeWithSelector(StdConfig.UnableToParseVariable.selector, "bad_value"));
378
+ new StdConfig(badParseConfig, false);
379
+ vm.removeFile(badParseConfig);
380
+ }
381
+ }