Skip to content

Commit c8ac949

Browse files
committed
feat: transfer da ownership zeus scripts
fix: modify less files forge fmt
1 parent f0ff053 commit c8ac949

5 files changed

+201
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.12;
3+
4+
import "../Env.sol";
5+
import {TransferDAOwnershipConstants as C} from "./TransferDAOwnershipConstants.sol";
6+
7+
import {MultisigBuilder} from "zeus-templates/templates/MultisigBuilder.sol";
8+
import "zeus-templates/utils/Encode.sol";
9+
10+
import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol";
11+
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
12+
13+
/**
14+
* Purpose:
15+
* * enqueue a multisig transaction which;
16+
* - transfers DA Proxy Admin ownership to the EigenDA ops multisig
17+
* This should be run via the protocol council multisig.
18+
*/
19+
contract QueueTransferProxyAdmin is MultisigBuilder {
20+
using Env for *;
21+
using Encode for *;
22+
23+
function _runAsMultisig() internal virtual override prank(Env.opsMultisig()) {
24+
bytes memory calldata_to_executor = _getCalldataToExecutor();
25+
26+
TimelockController timelock = Env.timelockController();
27+
timelock.schedule({
28+
target: Env.executorMultisig(),
29+
value: 0,
30+
data: calldata_to_executor,
31+
predecessor: 0,
32+
salt: 0,
33+
delay: timelock.getMinDelay()
34+
});
35+
}
36+
37+
/// @dev Get the calldata to be sent from the timelock to the executor
38+
function _getCalldataToExecutor() internal returns (bytes memory) {
39+
MultisigCall[] storage executorCalls = Encode.newMultisigCalls().append({
40+
to: C.EIGEN_DA_PROXY_ADMIN,
41+
data: abi.encodeCall(Ownable.transferOwnership, (C.EIGEN_DA_OPS_MULTISIG))
42+
});
43+
44+
return Encode.gnosisSafe.execTransaction({
45+
from: address(Env.timelockController()),
46+
to: Env.multiSendCallOnly(),
47+
op: Encode.Operation.DelegateCall,
48+
data: Encode.multiSend(executorCalls)
49+
});
50+
}
51+
52+
function testScript() public virtual {
53+
TimelockController timelock = Env.timelockController();
54+
bytes memory calldata_to_executor = _getCalldataToExecutor();
55+
bytes32 txHash = timelock.hashOperation({
56+
target: Env.executorMultisig(),
57+
value: 0,
58+
data: calldata_to_executor,
59+
predecessor: 0,
60+
salt: 0
61+
});
62+
63+
// Check that the upgrade does not exist in the timelock
64+
assertFalse(timelock.isOperationPending(txHash), "Transaction should NOT be queued.");
65+
66+
execute();
67+
68+
// Check that the upgrade has been added to the timelock
69+
assertTrue(timelock.isOperationPending(txHash), "Transaction should be queued.");
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.12;
3+
4+
import "../Env.sol";
5+
6+
import {MultisigBuilder} from "zeus-templates/templates/MultisigBuilder.sol";
7+
import {TransferDAOwnershipConstants as C} from "./TransferDAOwnershipConstants.sol";
8+
import "zeus-templates/utils/Encode.sol";
9+
10+
import "@openzeppelin/contracts/access/Ownable.sol";
11+
12+
/**
13+
* Purpose:
14+
* * enqueue a multisig transaction which;
15+
* - transfers DA contract ownership to the EigenDA ops multisig
16+
* This should be run via the core ops multisig.
17+
*/
18+
contract TransferOwnershipDAContracts is MultisigBuilder {
19+
using Env for *;
20+
21+
function _runAsMultisig() internal override prank(Env.opsMultisig()) {
22+
Ownable(C.EIGEN_DA_EJECTION_MANAGER).transferOwnership(C.EIGEN_DA_OPS_MULTISIG);
23+
Ownable(C.EIGEN_DA_REGISTRY_COORDINATOR).transferOwnership(C.EIGEN_DA_OPS_MULTISIG);
24+
Ownable(C.EIGEN_DA_SERVICE_MANAGER).transferOwnership(C.EIGEN_DA_OPS_MULTISIG);
25+
}
26+
27+
function testScript() public virtual {
28+
_runAsMultisig();
29+
30+
assertTrue(
31+
Ownable(C.EIGEN_DA_EJECTION_MANAGER).owner() == C.EIGEN_DA_OPS_MULTISIG,
32+
"eigenDAEjectionManager owner invalid"
33+
);
34+
assertTrue(
35+
Ownable(C.EIGEN_DA_REGISTRY_COORDINATOR).owner() == C.EIGEN_DA_OPS_MULTISIG,
36+
"eigenDARegistryCoordinator owner invalid"
37+
);
38+
assertTrue(
39+
Ownable(C.EIGEN_DA_SERVICE_MANAGER).owner() == C.EIGEN_DA_OPS_MULTISIG,
40+
"eigenDAServiceManager owner invalid"
41+
);
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.12;
3+
4+
import "../Env.sol";
5+
import {QueueTransferProxyAdmin} from "./1-queueTransferProxyAdmin.s.sol";
6+
import {TransferDAOwnershipConstants as C} from "./TransferDAOwnershipConstants.sol";
7+
8+
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
9+
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
10+
11+
contract ExecuteTransferProxyAdmin is QueueTransferProxyAdmin {
12+
using Env for *;
13+
14+
function _runAsMultisig() internal override prank(Env.protocolCouncilMultisig()) {
15+
bytes memory calldata_to_executor = _getCalldataToExecutor();
16+
17+
TimelockController timelock = Env.timelockController();
18+
timelock.execute({
19+
target: Env.executorMultisig(),
20+
value: 0,
21+
payload: calldata_to_executor,
22+
predecessor: 0,
23+
salt: 0
24+
});
25+
}
26+
27+
function testScript() public virtual override {
28+
TimelockController timelock = Env.timelockController();
29+
bytes memory calldata_to_executor = _getCalldataToExecutor();
30+
bytes32 txHash = timelock.hashOperation({
31+
target: Env.executorMultisig(),
32+
value: 0,
33+
data: calldata_to_executor,
34+
predecessor: 0,
35+
salt: 0
36+
});
37+
38+
assertFalse(timelock.isOperationPending(txHash), "Transaction should NOT be queued.");
39+
40+
// 1- run queueing logic
41+
QueueTransferProxyAdmin._runAsMultisig();
42+
_unsafeResetHasPranked(); // reset hasPranked so we can use it again
43+
44+
assertTrue(timelock.isOperationPending(txHash), "Transaction should be queued.");
45+
assertFalse(timelock.isOperationReady(txHash), "Transaction should NOT be ready for execution.");
46+
assertFalse(timelock.isOperationDone(txHash), "Transaction should NOT be complete.");
47+
48+
// 2- warp past delay
49+
vm.warp(block.timestamp + timelock.getMinDelay()); // 1 tick after ETA
50+
assertEq(timelock.isOperationReady(txHash), true, "Transaction should be executable.");
51+
52+
// 3- execute
53+
execute();
54+
55+
assertTrue(timelock.isOperationDone(txHash), "Transaction should be complete.");
56+
assertTrue(
57+
Ownable(C.EIGEN_DA_PROXY_ADMIN).owner() == C.EIGEN_DA_OPS_MULTISIG, "eigenDAProxyAdmin owner invalid"
58+
);
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.12;
3+
4+
library TransferDAOwnershipConstants {
5+
address internal constant EIGEN_DA_PROXY_ADMIN = 0x8247EF5705d3345516286B72bFE6D690197C2E99;
6+
address internal constant EIGEN_DA_OPS_MULTISIG = 0x002721B4790d97dC140a049936aA710152Ba92D5;
7+
address internal constant EIGEN_DA_EJECTION_MANAGER = 0x130d8EA0052B45554e4C99079B84df292149Bd5E;
8+
address internal constant EIGEN_DA_REGISTRY_COORDINATOR = 0x0BAAc79acD45A023E19345c352d8a7a83C4e5656;
9+
address internal constant EIGEN_DA_SERVICE_MANAGER = 0x870679E138bCdf293b7Ff14dD44b70FC97e12fc0;
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "transfer-da-ownership",
3+
"phases": [
4+
{
5+
"type": "multisig",
6+
"filename": "1-queueTransferProxyAdmin.s.sol"
7+
},
8+
{
9+
"type": "multisig",
10+
"filename": "2-transferOwnership.s.sol"
11+
},
12+
{
13+
"type": "multisig",
14+
"filename": "3-executeTransferProxyAdmin.s.sol"
15+
}
16+
]
17+
}

0 commit comments

Comments
 (0)