contracts/lib/forge-std/test/StdChains.t.sol 9.5 K raw
1
// SPDX-License-Identifier: MIT
2
pragma solidity >=0.7.0 <0.9.0;
3
4
import {Test} from "../src/Test.sol";
5
6
contract StdChainsMock is Test {
7
    function exposed_getChain(string memory chainAlias) public returns (Chain memory) {
8
        return getChain(chainAlias);
9
    }
10
11
    function exposed_getChain(uint256 chainId) public returns (Chain memory) {
12
        return getChain(chainId);
13
    }
14
15
    function exposed_setChain(string memory chainAlias, ChainData memory chainData) public {
16
        setChain(chainAlias, chainData);
17
    }
18
19
    function exposed_setFallbackToDefaultRpcUrls(bool useDefault) public {
20
        setFallbackToDefaultRpcUrls(useDefault);
21
    }
22
}
23
24
contract StdChainsTest is Test {
25
    function test_ChainRpcInitialization() public {
26
        // RPCs specified in `foundry.toml` should be updated.
27
        assertEq(getChain(1).rpcUrl, "https://eth.merkle.io");
28
        assertEq(getChain("optimism_sepolia").rpcUrl, "https://sepolia.optimism.io/");
29
        assertEq(getChain("arbitrum_one_sepolia").rpcUrl, "https://sepolia-rollup.arbitrum.io/rpc/");
30
31
        // Environment variables should be the next fallback
32
        assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc");
33
        vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride");
34
        assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride");
35
        vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc");
36
37
        // Cannot override RPCs defined in `foundry.toml`
38
        vm.setEnv("MAINNET_RPC_URL", "myoverride2");
39
        assertEq(getChain("mainnet").rpcUrl, "https://eth.merkle.io");
40
41
        // Other RPCs should remain unchanged.
42
        assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545");
43
        assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001");
44
    }
45
46
    // Named with a leading underscore to clarify this is not intended to be run as a normal test,
47
    // and is intended to be used in the below `test_Rpcs` test.
48
    function _testRpc(string memory rpcAlias) internal {
49
        string memory rpcUrl = getChain(rpcAlias).rpcUrl;
50
        vm.createSelectFork(rpcUrl);
51
    }
52
53
    // Ensure we can connect to the default RPC URL for each chain.
54
    // Currently commented out since this is slow and public RPCs are flaky, often resulting in failing CI.
55
    // function test_Rpcs() public {
56
    //     _testRpc("mainnet");
57
    //     _testRpc("sepolia");
58
    //     _testRpc("holesky");
59
    //     _testRpc("optimism");
60
    //     _testRpc("optimism_sepolia");
61
    //     _testRpc("arbitrum_one");
62
    //     _testRpc("arbitrum_one_sepolia");
63
    //     _testRpc("arbitrum_nova");
64
    //     _testRpc("polygon");
65
    //     _testRpc("polygon_amoy");
66
    //     _testRpc("avalanche");
67
    //     _testRpc("avalanche_fuji");
68
    //     _testRpc("bnb_smart_chain");
69
    //     _testRpc("bnb_smart_chain_testnet");
70
    //     _testRpc("gnosis_chain");
71
    //     _testRpc("moonbeam");
72
    //     _testRpc("moonriver");
73
    //     _testRpc("moonbase");
74
    //     _testRpc("base_sepolia");
75
    //     _testRpc("base");
76
    //     _testRpc("blast_sepolia");
77
    //     _testRpc("blast");
78
    //     _testRpc("fantom_opera");
79
    //     _testRpc("fantom_opera_testnet");
80
    //     _testRpc("fraxtal");
81
    //     _testRpc("fraxtal_testnet");
82
    //     _testRpc("berachain_bartio_testnet");
83
    //     _testRpc("flare");
84
    //     _testRpc("flare_coston2");
85
    // }
86
87
    function test_RevertIf_ChainNotFound() public {
88
        // We deploy a mock to properly test the revert.
89
        StdChainsMock stdChainsMock = new StdChainsMock();
90
91
        vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found.");
92
        stdChainsMock.exposed_getChain("does_not_exist");
93
    }
94
95
    function test_RevertIf_SetChain_ChainIdExist_FirstTest() public {
96
        // We deploy a mock to properly test the revert.
97
        StdChainsMock stdChainsMock = new StdChainsMock();
98
99
        vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\".");
100
        stdChainsMock.exposed_setChain("anvil2", ChainData("Anvil", 31337, "URL"));
101
    }
102
103
    function test_RevertIf_ChainBubbleUp() public {
104
        // We deploy a mock to properly test the revert.
105
        StdChainsMock stdChainsMock = new StdChainsMock();
106
107
        stdChainsMock.exposed_setChain("needs_undefined_env_var", ChainData("", 123456789, ""));
108
        // Forge environment variable error.
109
        vm.expectRevert();
110
        stdChainsMock.exposed_getChain("needs_undefined_env_var");
111
    }
112
113
    function test_RevertIf_SetChain_ChainIdExists_SecondTest() public {
114
        // We deploy a mock to properly test the revert.
115
        StdChainsMock stdChainsMock = new StdChainsMock();
116
117
        stdChainsMock.exposed_setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/"));
118
119
        vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".');
120
121
        stdChainsMock.exposed_setChain("another_custom_chain", ChainData("", 123456789, ""));
122
    }
123
124
    function test_SetChain() public {
125
        setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/"));
126
        Chain memory customChain = getChain("custom_chain");
127
        assertEq(customChain.name, "Custom Chain");
128
        assertEq(customChain.chainId, 123456789);
129
        assertEq(customChain.chainAlias, "custom_chain");
130
        assertEq(customChain.rpcUrl, "https://custom.chain/");
131
        Chain memory chainById = getChain(123456789);
132
        assertEq(chainById.name, customChain.name);
133
        assertEq(chainById.chainId, customChain.chainId);
134
        assertEq(chainById.chainAlias, customChain.chainAlias);
135
        assertEq(chainById.rpcUrl, customChain.rpcUrl);
136
        customChain.name = "Another Custom Chain";
137
        customChain.chainId = 987654321;
138
        setChain("another_custom_chain", customChain);
139
        Chain memory anotherCustomChain = getChain("another_custom_chain");
140
        assertEq(anotherCustomChain.name, "Another Custom Chain");
141
        assertEq(anotherCustomChain.chainId, 987654321);
142
        assertEq(anotherCustomChain.chainAlias, "another_custom_chain");
143
        assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/");
144
        // Verify the first chain data was not overwritten
145
        chainById = getChain(123456789);
146
        assertEq(chainById.name, "Custom Chain");
147
        assertEq(chainById.chainId, 123456789);
148
    }
149
150
    function test_RevertIf_SetEmptyAlias() public {
151
        // We deploy a mock to properly test the revert.
152
        StdChainsMock stdChainsMock = new StdChainsMock();
153
154
        vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string.");
155
        stdChainsMock.exposed_setChain("", ChainData("", 123456789, ""));
156
    }
157
158
    function test_RevertIf_SetNoChainId0() public {
159
        // We deploy a mock to properly test the revert.
160
        StdChainsMock stdChainsMock = new StdChainsMock();
161
162
        vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0.");
163
        stdChainsMock.exposed_setChain("alias", ChainData("", 0, ""));
164
    }
165
166
    function test_RevertIf_GetNoChainId0() public {
167
        // We deploy a mock to properly test the revert.
168
        StdChainsMock stdChainsMock = new StdChainsMock();
169
170
        vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0.");
171
        stdChainsMock.exposed_getChain(0);
172
    }
173
174
    function test_RevertIf_GetNoEmptyAlias() public {
175
        // We deploy a mock to properly test the revert.
176
        StdChainsMock stdChainsMock = new StdChainsMock();
177
178
        vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string.");
179
        stdChainsMock.exposed_getChain("");
180
    }
181
182
    function test_RevertIf_ChainIdNotFound() public {
183
        // We deploy a mock to properly test the revert.
184
        StdChainsMock stdChainsMock = new StdChainsMock();
185
186
        vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found.");
187
        stdChainsMock.exposed_getChain("no_such_alias");
188
    }
189
190
    function test_RevertIf_ChainAliasNotFound() public {
191
        // We deploy a mock to properly test the revert.
192
        StdChainsMock stdChainsMock = new StdChainsMock();
193
194
        vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found.");
195
196
        stdChainsMock.exposed_getChain(321);
197
    }
198
199
    function test_SetChain_ExistingOne() public {
200
        // We deploy a mock to properly test the revert.
201
        StdChainsMock stdChainsMock = new StdChainsMock();
202
203
        setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/"));
204
        assertEq(getChain(123456789).chainId, 123456789);
205
206
        setChain("custom_chain", ChainData("Modified Chain", 9999999999999999999, "https://modified.chain/"));
207
        vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found.");
208
        stdChainsMock.exposed_getChain(123456789);
209
210
        Chain memory modifiedChain = getChain(9999999999999999999);
211
        assertEq(modifiedChain.name, "Modified Chain");
212
        assertEq(modifiedChain.chainId, 9999999999999999999);
213
        assertEq(modifiedChain.rpcUrl, "https://modified.chain/");
214
    }
215
216
    function test_RevertIf_DontUseDefaultRpcUrl() public {
217
        // We deploy a mock to properly test the revert.
218
        StdChainsMock stdChainsMock = new StdChainsMock();
219
220
        // Should error if default RPCs flag is set to false.
221
        stdChainsMock.exposed_setFallbackToDefaultRpcUrls(false);
222
        vm.expectRevert();
223
        stdChainsMock.exposed_getChain(31337);
224
        vm.expectRevert();
225
        stdChainsMock.exposed_getChain("sepolia");
226
    }
227
}