@bananapus/address-registry-v6 0.0.19 → 0.0.21
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.
package/package.json
CHANGED
|
@@ -72,6 +72,8 @@ library AddressRegistryDeploymentLib {
|
|
|
72
72
|
string memory deploymentJson =
|
|
73
73
|
// forge-lint: disable-next-line(unsafe-cheatcode)
|
|
74
74
|
vm.readFile(string.concat(path, projectName, "/", networkName, "/", contractName, ".json"));
|
|
75
|
-
|
|
75
|
+
address deployed = stdJson.readAddress({json: deploymentJson, key: ".address"});
|
|
76
|
+
require(deployed.code.length != 0, "AddressRegistryDeploymentLib: registry has no code");
|
|
77
|
+
return deployed;
|
|
76
78
|
}
|
|
77
79
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.28;
|
|
3
|
+
|
|
4
|
+
import {Test} from "forge-std/Test.sol";
|
|
5
|
+
|
|
6
|
+
import {JBAddressRegistry} from "src/JBAddressRegistry.sol";
|
|
7
|
+
|
|
8
|
+
contract CodexUnauthorizedRegistrarTest is Test {
|
|
9
|
+
JBAddressRegistry internal registry;
|
|
10
|
+
address internal deployer = makeAddr("deployer");
|
|
11
|
+
address internal attacker = makeAddr("attacker");
|
|
12
|
+
|
|
13
|
+
function setUp() public {
|
|
14
|
+
registry = new JBAddressRegistry();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function test_attackerCanFinalizeCreateRegistrationForAnotherDeployersContract() external {
|
|
18
|
+
uint64 nonce = 7;
|
|
19
|
+
vm.setNonce(deployer, nonce);
|
|
20
|
+
|
|
21
|
+
vm.prank(deployer);
|
|
22
|
+
address deployed = address(new MockDeployment());
|
|
23
|
+
|
|
24
|
+
vm.prank(attacker);
|
|
25
|
+
registry.registerAddress(deployer, nonce);
|
|
26
|
+
|
|
27
|
+
assertEq(registry.deployerOf(deployed), deployer, "attacker should be able to write the record");
|
|
28
|
+
|
|
29
|
+
vm.prank(deployer);
|
|
30
|
+
vm.expectRevert(
|
|
31
|
+
abi.encodeWithSelector(JBAddressRegistry.JBAddressRegistry_AlreadyRegistered.selector, deployed)
|
|
32
|
+
);
|
|
33
|
+
registry.registerAddress(deployer, nonce);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function test_attackerCanFinalizeCreate2RegistrationForAnotherDeployersContract() external {
|
|
37
|
+
Create2Factory factory = new Create2Factory();
|
|
38
|
+
bytes32 salt = keccak256("salt");
|
|
39
|
+
address deployed = factory.deploy(salt);
|
|
40
|
+
|
|
41
|
+
vm.prank(attacker);
|
|
42
|
+
registry.registerAddress(address(factory), salt, type(MockDeployment).creationCode);
|
|
43
|
+
|
|
44
|
+
assertEq(registry.deployerOf(deployed), address(factory), "attacker should be able to write the record");
|
|
45
|
+
|
|
46
|
+
vm.expectRevert(
|
|
47
|
+
abi.encodeWithSelector(JBAddressRegistry.JBAddressRegistry_AlreadyRegistered.selector, deployed)
|
|
48
|
+
);
|
|
49
|
+
registry.registerAddress(address(factory), salt, type(MockDeployment).creationCode);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
contract Create2Factory {
|
|
54
|
+
function deploy(bytes32 salt) external returns (address deployed) {
|
|
55
|
+
deployed = address(new MockDeployment{salt: salt}());
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
contract MockDeployment {}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.28;
|
|
3
|
+
|
|
4
|
+
import {Test} from "forge-std/Test.sol";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
AddressRegistryDeploymentLib,
|
|
8
|
+
AddressRegistryDeployment
|
|
9
|
+
} from "../../script/helpers/AddressRegistryDeploymentLib.sol";
|
|
10
|
+
|
|
11
|
+
/// @notice Wrapper that exposes the library's chain-aware overload.
|
|
12
|
+
contract DeploymentLibAutoCaller {
|
|
13
|
+
function getDeployment(string memory path) external returns (AddressRegistryDeployment memory) {
|
|
14
|
+
return AddressRegistryDeploymentLib.getDeployment(path);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/// @notice Verifies that auto-discovering the network name has an on-chain side effect.
|
|
19
|
+
contract DeploymentHelperNonceSideEffectTest is Test {
|
|
20
|
+
DeploymentLibAutoCaller internal caller;
|
|
21
|
+
|
|
22
|
+
function setUp() public {
|
|
23
|
+
caller = new DeploymentLibAutoCaller();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function test_getDeployment_pathOverloadConsumesCallersCreateNonce() external {
|
|
27
|
+
address registry = makeAddr("registryContract");
|
|
28
|
+
vm.etch(registry, hex"6080604052");
|
|
29
|
+
|
|
30
|
+
string memory json = string.concat('{"address":"', vm.toString(registry), '"}');
|
|
31
|
+
string memory dir = "test/audit/tmp-nonce/nana-address-registry-v6/anvil/";
|
|
32
|
+
string memory file = string.concat(dir, "JBAddressRegistry.json");
|
|
33
|
+
|
|
34
|
+
vm.createDir(dir, true);
|
|
35
|
+
vm.writeFile(file, json);
|
|
36
|
+
|
|
37
|
+
uint64 nonceBefore = vm.getNonce(address(caller));
|
|
38
|
+
|
|
39
|
+
caller.getDeployment("test/audit/tmp-nonce/");
|
|
40
|
+
|
|
41
|
+
uint64 nonceAfter = vm.getNonce(address(caller));
|
|
42
|
+
|
|
43
|
+
assertEq(nonceAfter, nonceBefore + 1, "library should deploy SphinxConstants and consume one CREATE nonce");
|
|
44
|
+
|
|
45
|
+
vm.removeFile(file);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.28;
|
|
3
|
+
|
|
4
|
+
import {Test} from "forge-std/Test.sol";
|
|
5
|
+
import {stdJson} from "forge-std/Script.sol";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
AddressRegistryDeploymentLib,
|
|
9
|
+
AddressRegistryDeployment
|
|
10
|
+
} from "../../script/helpers/AddressRegistryDeploymentLib.sol";
|
|
11
|
+
|
|
12
|
+
/// @notice Wrapper that makes the library's internal functions callable externally so vm.expectRevert works.
|
|
13
|
+
contract DeploymentLibCaller {
|
|
14
|
+
function getDeployment(
|
|
15
|
+
string memory path,
|
|
16
|
+
string memory networkName
|
|
17
|
+
)
|
|
18
|
+
external
|
|
19
|
+
returns (AddressRegistryDeployment memory)
|
|
20
|
+
{
|
|
21
|
+
return AddressRegistryDeploymentLib.getDeployment({path: path, networkName: networkName});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// @notice Tests M-40: Deployment helper rejects stale artifacts pointing to non-contract addresses.
|
|
26
|
+
contract DeploymentHelperValidationTest is Test {
|
|
27
|
+
DeploymentLibCaller internal caller;
|
|
28
|
+
|
|
29
|
+
function setUp() public {
|
|
30
|
+
caller = new DeploymentLibCaller();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// @notice Stale deployment artifact pointing to an EOA reverts.
|
|
34
|
+
function test_deploymentHelper_revertsForEOARegistry() external {
|
|
35
|
+
address eoa = makeAddr("staleEOA");
|
|
36
|
+
string memory json = string.concat('{"address":"', vm.toString(eoa), '"}');
|
|
37
|
+
|
|
38
|
+
string memory dir = "test/audit/tmp-eoa/nana-address-registry-v6/testnet/";
|
|
39
|
+
vm.createDir(dir, true);
|
|
40
|
+
vm.writeFile(string.concat(dir, "JBAddressRegistry.json"), json);
|
|
41
|
+
|
|
42
|
+
vm.expectRevert("AddressRegistryDeploymentLib: registry has no code");
|
|
43
|
+
caller.getDeployment({path: "test/audit/tmp-eoa/", networkName: "testnet"});
|
|
44
|
+
|
|
45
|
+
vm.removeFile(string.concat(dir, "JBAddressRegistry.json"));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// @notice Valid deployment artifact with a contract address is accepted.
|
|
49
|
+
function test_deploymentHelper_acceptsContractRegistry() external {
|
|
50
|
+
address registry = makeAddr("registryContract");
|
|
51
|
+
vm.etch(registry, hex"6080604052");
|
|
52
|
+
string memory json = string.concat('{"address":"', vm.toString(registry), '"}');
|
|
53
|
+
|
|
54
|
+
string memory dir = "test/audit/tmp-contract/nana-address-registry-v6/testnet/";
|
|
55
|
+
vm.createDir(dir, true);
|
|
56
|
+
vm.writeFile(string.concat(dir, "JBAddressRegistry.json"), json);
|
|
57
|
+
|
|
58
|
+
caller.getDeployment({path: "test/audit/tmp-contract/", networkName: "testnet"});
|
|
59
|
+
|
|
60
|
+
vm.removeFile(string.concat(dir, "JBAddressRegistry.json"));
|
|
61
|
+
}
|
|
62
|
+
}
|