Skip to content

Commit 3d40036

Browse files
committed
feat: add alchemy proxy registry
1 parent 79b784e commit 3d40036

File tree

8 files changed

+83
-57
lines changed

8 files changed

+83
-57
lines changed

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
[submodule "lib/forge-std"]
22
path = lib/forge-std
33
url = https://github.com/foundry-rs/forge-std
4+
[submodule "lib/openzeppelin-contracts-upgradeable"]
5+
path = lib/openzeppelin-contracts-upgradeable
6+
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
7+
[submodule "lib/openzeppelin-contracts"]
8+
path = lib/openzeppelin-contracts
9+
url = https://github.com/OpenZeppelin/openzeppelin-contracts

lib/openzeppelin-contracts

Submodule openzeppelin-contracts added at e4f7021

script/Counter.s.sol

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/AlchemyProxyRegistry.sol

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
5+
6+
/**
7+
* @title AlchemyProxyRegistry
8+
* @author Alchemy
9+
* @notice A registry for getting the same address for proxies regardless of their implementation
10+
*/
11+
contract AlchemyProxyRegistry is UUPSUpgradeable {
12+
address public immutable deployer;
13+
14+
constructor(address _deployer) {
15+
deployer = _deployer;
16+
}
17+
18+
// upgrades can only be made by the deployer
19+
function _authorizeUpgrade(address) internal view override {
20+
require(msg.sender == deployer, "Only deployer can upgrade");
21+
}
22+
}

src/Counter.sol

Lines changed: 0 additions & 14 deletions
This file was deleted.

test/AlchemyProxyRegistry.t.sol

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity ^0.8.13;
3+
4+
import {Test, console} from "forge-std/Test.sol";
5+
import {AlchemyProxyRegistry} from "../src/AlchemyProxyRegistry.sol";
6+
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
7+
8+
contract AlchemyProxyRegistryTest is Test {
9+
AlchemyProxyRegistry public proxyRegistry;
10+
bytes32 internal immutable _PROXY_IMPL_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
11+
12+
function setUp() public {
13+
proxyRegistry = new AlchemyProxyRegistry(address(this));
14+
}
15+
16+
function test_deploys() public {
17+
// check that owner is test contract
18+
assertEq(address(proxyRegistry.deployer()), address(this));
19+
20+
address proxy = address(new ERC1967Proxy(address(proxyRegistry), ""));
21+
22+
// instance of implementation to test upgradeTo
23+
address toUpgradeTo = address(new AlchemyProxyRegistry(address(this)));
24+
25+
assertEq(_getImplementation(proxy), address(proxyRegistry));
26+
AlchemyProxyRegistry(proxy).upgradeToAndCall(toUpgradeTo, "");
27+
28+
// check that implementation is now the new implementation
29+
assertEq(_getImplementation(proxy), address(toUpgradeTo));
30+
}
31+
32+
function test_deployBad() public {
33+
// check that owner is test contract
34+
assertEq(address(proxyRegistry.deployer()), address(this));
35+
36+
address proxy = address(new ERC1967Proxy(address(proxyRegistry), ""));
37+
38+
// instance of implementation to test upgradeTo
39+
address toUpgradeTo = address(new AlchemyProxyRegistry(address(this)));
40+
41+
assertEq(_getImplementation(proxy), address(proxyRegistry));
42+
vm.startPrank(address(1));
43+
vm.expectRevert("Only deployer can upgrade");
44+
AlchemyProxyRegistry(proxy).upgradeToAndCall(toUpgradeTo, "");
45+
46+
// check that implementation is still the old implementation
47+
assertEq(_getImplementation(proxy), address(proxyRegistry));
48+
}
49+
50+
function _getImplementation(address proxy) internal view returns (address) {
51+
return address(uint160(uint256(vm.load(address(proxy), _PROXY_IMPL_SLOT))));
52+
}
53+
}

test/Counter.t.sol

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)