Skip to content

Commit f957940

Browse files
committed
feat: ownership transfer script can set arbitrary manager
1 parent 5957d67 commit f957940

File tree

3 files changed

+37
-21
lines changed

3 files changed

+37
-21
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ The following parameters can be set:
142142

143143
```sh
144144
export ETH_RPC_URL='https://rpc.url.example.com'
145-
export NEW_OWNER=0x1111111111111111111111111111111111111111
146-
export RESET_MANAGER=true # true if the new owner should also become the manager, false otherwise
145+
export NEW_OWNER=0x1111111111111111111111111111111111111111
146+
export NEW_MANAGER=0x2222222222222222222222222222222222222222 # optional parameter, the manager does not change if this variable is unset
147147
```
148148

149149
To test run the script from a specific owner (sender):
@@ -155,7 +155,7 @@ forge script script/TransferOwnership.s.sol:TransferOwnership --rpc-url "$ETH_RP
155155
To actually execute the transaction:
156156

157157
```sh
158-
forge script script/TransferOwnership.s.sol:TransferOwnership --rpc-url "$ETH_RPC_URL" --private-key 0x0000000000000000000000000000000000000000000000000000000000000001 --broadcast
158+
forge script script/TransferOwnership.s.sol:TransferOwnership --rpc-url "$ETH_RPC_URL" --private-key 0x0000000000000000000000000000000000000000000000000000000000000001 --broadcast --slow
159159
```
160160

161161
## Releases

script/TransferOwnership.s.sol

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,19 @@ import {NetworksJson} from "./lib/NetworksJson.sol";
1111
contract TransferOwnership is NetworksJson {
1212
// Required input
1313
string private constant INPUT_ENV_NEW_OWNER = "NEW_OWNER";
14-
string private constant INPUT_ENV_RESET_MANAGER = "RESET_MANAGER";
14+
string private constant INPUT_ENV_NEW_MANAGER = "NEW_MANAGER";
1515
// Optional input
1616
string private constant INPUT_ENV_AUTHENTICATOR_PROXY = "AUTHENTICATOR_PROXY";
1717

18+
address public constant NO_MANAGER = address(0);
19+
1820
NetworksJson internal networksJson;
1921

2022
struct ScriptParams {
2123
address newOwner;
22-
bool resetManager;
24+
/// Contains either the value `NO_MANAGER` if the manager should not be
25+
/// updated or the address of the new manager.
26+
address newManager;
2327
ERC173 authenticatorProxy;
2428
}
2529

@@ -46,17 +50,17 @@ contract TransferOwnership is NetworksJson {
4650

4751
// Make sure to reset the manager BEFORE transferring ownership, or else
4852
// we will not be able to do it once we lose permissions.
49-
if (params.resetManager) {
53+
if (params.newManager != NO_MANAGER) {
5054
console.log(
5155
string.concat(
5256
"Setting new solver manager from ",
5357
vm.toString(authenticator.manager()),
5458
" to ",
55-
vm.toString(params.newOwner)
59+
vm.toString(params.newManager)
5660
)
5761
);
5862
vm.broadcast(msg.sender);
59-
authenticator.setManager(params.newOwner);
63+
authenticator.setManager(params.newManager);
6064
console.log("Set new solver manager account.");
6165
}
6266

@@ -68,11 +72,23 @@ contract TransferOwnership is NetworksJson {
6872
vm.broadcast(msg.sender);
6973
params.authenticatorProxy.transferOwnership(params.newOwner);
7074
console.log("Set new owner of the authenticator proxy.");
75+
76+
console.log(string.concat("Final owner: ", vm.toString(params.authenticatorProxy.owner())));
77+
console.log(string.concat("Final manager: ", vm.toString(authenticator.manager())));
7178
}
7279

7380
function paramsFromEnv() internal view returns (ScriptParams memory) {
7481
address newOwner = vm.envAddress(INPUT_ENV_NEW_OWNER);
75-
bool resetManager = vm.envBool(INPUT_ENV_RESET_MANAGER);
82+
83+
address newManager;
84+
try vm.envAddress(INPUT_ENV_NEW_MANAGER) returns (address env) {
85+
if (env == NO_MANAGER) {
86+
revert(string.concat("Invalid parameter: cannot update the manager to address ", vm.toString(env)));
87+
}
88+
newManager = env;
89+
} catch {
90+
newManager = NO_MANAGER;
91+
}
7692

7793
address authenticatorProxy;
7894
try vm.envAddress(INPUT_ENV_AUTHENTICATOR_PROXY) returns (address env) {
@@ -95,11 +111,8 @@ contract TransferOwnership is NetworksJson {
95111
}
96112
}
97113

98-
return ScriptParams({
99-
newOwner: newOwner,
100-
resetManager: resetManager,
101-
authenticatorProxy: ERC173(authenticatorProxy)
102-
});
114+
return
115+
ScriptParams({newOwner: newOwner, newManager: newManager, authenticatorProxy: ERC173(authenticatorProxy)});
103116
}
104117

105118
function checkIsProxy(address candidate) internal view {

test/script/TransferOwnership.t.sol

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,30 @@ contract TestTransferOwnership is Test {
3030
proxyAsAuthenticator = GPv2AllowListAuthentication(deployed);
3131
}
3232

33-
function test_transfers_proxy_ownership_and_resets_manager() public {
33+
function test_transfers_proxy_ownership_and_updates_manager() public {
3434
address newOwner = makeAddr("TestTransferOwnership: new proxy owner");
35+
address newManager = makeAddr("TestTransferOwnership: new authenticator manager");
3536
assertEq(proxy.owner(), owner);
3637
assertEq(proxyAsAuthenticator.manager(), owner);
3738

3839
TransferOwnership.ScriptParams memory params =
39-
TransferOwnership.ScriptParams({newOwner: newOwner, authenticatorProxy: proxy, resetManager: true});
40+
TransferOwnership.ScriptParams({newOwner: newOwner, authenticatorProxy: proxy, newManager: newManager});
4041

4142
script.runWith(params);
4243

4344
assertEq(proxy.owner(), newOwner, "did not change the owner");
44-
assertEq(proxyAsAuthenticator.manager(), newOwner, "did not change the manager");
45+
assertEq(proxyAsAuthenticator.manager(), newManager, "did not change the manager");
4546
}
4647

4748
function test_only_transfers_proxy_ownership() public {
4849
address newOwner = makeAddr("TestTransferOwnership: new proxy owner");
4950
assertEq(proxy.owner(), owner);
5051
assertEq(proxyAsAuthenticator.manager(), owner);
5152

53+
address NO_MANAGER = script.NO_MANAGER();
54+
require(owner != NO_MANAGER, "Invalid test setup, owner should not coincide with NO_MANAGER flag address");
5255
TransferOwnership.ScriptParams memory params =
53-
TransferOwnership.ScriptParams({newOwner: newOwner, authenticatorProxy: proxy, resetManager: false});
56+
TransferOwnership.ScriptParams({newOwner: newOwner, authenticatorProxy: proxy, newManager: NO_MANAGER});
5457

5558
script.runWith(params);
5659

@@ -63,7 +66,7 @@ contract TestTransferOwnership is Test {
6366
TransferOwnership.ScriptParams memory params = TransferOwnership.ScriptParams({
6467
newOwner: makeAddr("some owner"),
6568
authenticatorProxy: ERC173(notAProxy),
66-
resetManager: false
69+
newManager: makeAddr("some manager")
6770
});
6871

6972
vm.expectRevert(bytes(string.concat("No code at target authenticator proxy ", vm.toString(notAProxy), ".")));
@@ -75,7 +78,7 @@ contract TestTransferOwnership is Test {
7578
TransferOwnership.ScriptParams memory params = TransferOwnership.ScriptParams({
7679
newOwner: makeAddr("some owner"),
7780
authenticatorProxy: ERC173(noERC173Proxy),
78-
resetManager: false
81+
newManager: makeAddr("some manager")
7982
});
8083
vm.etch(noERC173Proxy, hex"1337");
8184
vm.mockCall(
@@ -99,7 +102,7 @@ contract TestTransferOwnership is Test {
99102
TransferOwnership.ScriptParams memory params = TransferOwnership.ScriptParams({
100103
newOwner: makeAddr("some owner"),
101104
authenticatorProxy: ERC173(revertingProxy),
102-
resetManager: false
105+
newManager: makeAddr("some manager")
103106
});
104107
vm.etch(revertingProxy, hex"1337");
105108
vm.mockCallRevert(

0 commit comments

Comments
 (0)