Skip to content

Commit 9c6fb72

Browse files
ypatil128sunyuan
authored andcommitted
feat: slashing patch
1 parent dd8204b commit 9c6fb72

File tree

3 files changed

+197
-2
lines changed

3 files changed

+197
-2
lines changed

script/releases/v1.0.1-slashing/1-eoa.s.sol

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
1010
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
1111

1212
contract Deploy is EOADeployer {
13-
using EigenLabsUpgrade for *;
13+
using Env for *;
1414

1515
function _runAsEOA() internal override {
1616
vm.startBroadcast();
@@ -42,11 +42,35 @@ contract Deploy is EOADeployer {
4242

4343
function testDeploy() public virtual {
4444
_runAsEOA();
45-
45+
_validateNewImplAddresses(false);
4646
_validateImplConstructors();
4747
_validateImplsInitialized();
4848
}
4949

50+
51+
/// @dev Validate that the `Env.impl` addresses are updated to be distinct from what the proxy
52+
/// admin reports as the current implementation address.
53+
///
54+
/// Note: The upgrade script can call this with `areMatching == true` to check that these impl
55+
/// addresses _are_ matches.
56+
function _validateNewImplAddresses(bool areMatching) internal view {
57+
function (address, address, string memory) internal pure assertion =
58+
areMatching ? _assertMatch : _assertNotMatch;
59+
60+
61+
assertion(
62+
_getProxyImpl(address(Env.proxy.delegationManager())),
63+
address(Env.impl.delegationManager()),
64+
"delegationManager impl failed"
65+
);
66+
67+
assertion(
68+
_getProxyImpl(address(Env.proxy.allocationManager())),
69+
address(Env.impl.allocationManager()),
70+
"allocationManager impl failed"
71+
);
72+
}
73+
5074
/// @dev Validate the immutables set in the new implementation constructors
5175
function _validateImplConstructors() internal view {
5276
AllocationManager allocationManager = Env.impl.allocationManager();
@@ -78,4 +102,22 @@ contract Deploy is EOADeployer {
78102
vm.expectRevert(errInit);
79103
delegation.initialize(address(0), 0);
80104
}
105+
106+
/// @dev Query and return `proxyAdmin.getProxyImplementation(proxy)`
107+
function _getProxyImpl(address proxy) internal view returns (address) {
108+
return ProxyAdmin(Env.proxyAdmin()).getProxyImplementation(ITransparentUpgradeableProxy(proxy));
109+
}
110+
111+
/// @dev Query and return `proxyAdmin.getProxyAdmin(proxy)`
112+
function _getProxyAdmin(address proxy) internal view returns (address) {
113+
return ProxyAdmin(Env.proxyAdmin()).getProxyAdmin(ITransparentUpgradeableProxy(proxy));
114+
}
115+
116+
function _assertMatch(address a, address b, string memory err) private pure {
117+
assertEq(a, b, err);
118+
}
119+
120+
function _assertNotMatch(address a, address b, string memory err) private pure {
121+
assertNotEq(a, b, err);
122+
}
81123
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.12;
3+
4+
import {Deploy} from "./1-eoa.s.sol";
5+
import "../Env.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+
12+
contract Queue is MultisigBuilder, Deploy {
13+
using Env for *;
14+
using Encode for *;
15+
16+
function _runAsMultisig() prank(Env.opsMultisig()) internal virtual override {
17+
bytes memory calldata_to_executor = _getCalldataToExecutor();
18+
19+
TimelockController timelock = Env.timelockController();
20+
timelock.schedule({
21+
target: Env.executorMultisig(),
22+
value: 0,
23+
data: calldata_to_executor,
24+
predecessor: 0,
25+
salt: 0,
26+
delay: timelock.getMinDelay()
27+
});
28+
}
29+
30+
/// @dev Get the calldata to be sent from the timelock to the executor
31+
function _getCalldataToExecutor() internal returns (bytes memory) {
32+
MultisigCall[] storage executorCalls = Encode.newMultisigCalls()
33+
/// core/
34+
.append({
35+
to: Env.proxyAdmin(),
36+
data: Encode.proxyAdmin.upgrade({
37+
proxy: address(Env.proxy.allocationManager()),
38+
impl: address(Env.impl.allocationManager())
39+
})
40+
})
41+
.append({
42+
to: Env.proxyAdmin(),
43+
data: Encode.proxyAdmin.upgrade({
44+
proxy: address(Env.proxy.delegationManager()),
45+
impl: address(Env.impl.delegationManager())
46+
})
47+
});
48+
49+
return Encode.gnosisSafe.execTransaction({
50+
from: address(Env.timelockController()),
51+
to: address(Env.multiSendCallOnly()),
52+
op: Encode.Operation.DelegateCall,
53+
data: Encode.multiSend(executorCalls)
54+
});
55+
}
56+
57+
function testScript() public virtual {
58+
runAsEOA();
59+
60+
TimelockController timelock = Env.timelockController();
61+
bytes memory calldata_to_executor = _getCalldataToExecutor();
62+
bytes32 txHash = timelock.hashOperation({
63+
target: Env.executorMultisig(),
64+
value: 0,
65+
data: calldata_to_executor,
66+
predecessor: 0,
67+
salt: 0
68+
});
69+
70+
// Check that the upgrade does not exist in the timelock
71+
assertFalse(timelock.isOperationPending(txHash), "Transaction should NOT be queued.");
72+
73+
execute();
74+
75+
// Check that the upgrade has been added to the timelock
76+
assertTrue(timelock.isOperationPending(txHash), "Transaction should be queued.");
77+
}
78+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.12;
3+
4+
import "../Env.sol";
5+
import {Queue} from "./2-multisig.s.sol";
6+
7+
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
8+
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
9+
10+
contract Execute is Queue {
11+
using Env for *;
12+
13+
function _runAsMultisig() prank(Env.protocolCouncilMultisig()) internal override(Queue) {
14+
bytes memory calldata_to_executor = _getCalldataToExecutor();
15+
16+
TimelockController timelock = Env.timelockController();
17+
timelock.execute({
18+
target: Env.executorMultisig(),
19+
value: 0,
20+
payload: calldata_to_executor,
21+
predecessor: 0,
22+
salt: 0
23+
});
24+
}
25+
26+
function testScript() public virtual override(Queue){
27+
// 0. Deploy Impls
28+
runAsEOA();
29+
30+
TimelockController timelock = Env.timelockController();
31+
bytes memory calldata_to_executor = _getCalldataToExecutor();
32+
bytes32 txHash = timelock.hashOperation({
33+
target: Env.executorMultisig(),
34+
value: 0,
35+
data: calldata_to_executor,
36+
predecessor: 0,
37+
salt: 0
38+
});
39+
assertFalse(timelock.isOperationPending(txHash), "Transaction should NOT be queued.");
40+
41+
// 1. Queue Upgrade
42+
Queue._runAsMultisig();
43+
_unsafeResetHasPranked(); // reset hasPranked so we can use it again
44+
45+
// 2. Warp past delay
46+
vm.warp(block.timestamp + timelock.getMinDelay()); // 1 tick after ETA
47+
assertEq(timelock.isOperationReady(txHash), true, "Transaction should be executable.");
48+
49+
// 3- execute
50+
execute();
51+
52+
assertTrue(timelock.isOperationDone(txHash), "Transaction should be complete.");
53+
54+
// 4. Validate
55+
_validateNewImplAddresses(true);
56+
_validateProxyConstructors();
57+
}
58+
59+
function _validateProxyConstructors() internal view {
60+
AllocationManager allocationManager = Env.proxy.allocationManager();
61+
assertTrue(allocationManager.delegation() == Env.proxy.delegationManager(), "alm.dm invalid");
62+
assertTrue(allocationManager.pauserRegistry() == Env.impl.pauserRegistry(), "alm.pR invalid");
63+
assertTrue(allocationManager.permissionController() == Env.proxy.permissionController(), "alm.pc invalid");
64+
assertTrue(allocationManager.DEALLOCATION_DELAY() == Env.MIN_WITHDRAWAL_DELAY(), "alm.deallocDelay invalid");
65+
assertTrue(allocationManager.ALLOCATION_CONFIGURATION_DELAY() == Env.ALLOCATION_CONFIGURATION_DELAY(), "alm.configDelay invalid");
66+
67+
DelegationManager delegation = Env.proxy.delegationManager();
68+
assertTrue(delegation.strategyManager() == Env.proxy.strategyManager(), "dm.sm invalid");
69+
assertTrue(delegation.eigenPodManager() == Env.proxy.eigenPodManager(), "dm.epm invalid");
70+
assertTrue(delegation.allocationManager() == Env.proxy.allocationManager(), "dm.alm invalid");
71+
assertTrue(delegation.pauserRegistry() == Env.impl.pauserRegistry(), "dm.pR invalid");
72+
assertTrue(delegation.permissionController() == Env.proxy.permissionController(), "dm.pc invalid");
73+
assertTrue(delegation.minWithdrawalDelayBlocks() == Env.MIN_WITHDRAWAL_DELAY(), "dm.withdrawalDelay invalid");
74+
}
75+
}

0 commit comments

Comments
 (0)