From 0fb34edca2ad2f92bbdac498c7adf77cdb6ad9ee Mon Sep 17 00:00:00 2001 From: dzgoldman Date: Thu, 11 Jan 2024 12:32:31 -0500 Subject: [PATCH 1/4] sc improvement action contracts --- .../AIPIncreaseCoreTimelockDelayAction.sol | 16 +++++++++ ...PIncreaseNonEmergencySCThresholdAction.sol | 12 +++++++ .../governance/SetSCThresholdAction.sol | 33 +++++++++++++++++++ .../UpdateCoreTimelockDelayAction.sol | 21 ++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 src/gov-action-contracts/AIPs/SCImprovementAIP/AIPIncreaseCoreTimelockDelayAction.sol create mode 100644 src/gov-action-contracts/AIPs/SCImprovementAIP/AIPIncreaseNonEmergencySCThresholdAction.sol create mode 100644 src/gov-action-contracts/governance/SetSCThresholdAction.sol create mode 100644 src/gov-action-contracts/governance/UpdateCoreTimelockDelayAction.sol diff --git a/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPIncreaseCoreTimelockDelayAction.sol b/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPIncreaseCoreTimelockDelayAction.sol new file mode 100644 index 000000000..aec11c0b0 --- /dev/null +++ b/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPIncreaseCoreTimelockDelayAction.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.16; + +import "../../governance/UpdateCoreTimelockDelayAction.sol"; +import "../../address-registries/L2AddressRegistry.sol"; + +///@notice Increase core timelock day to eight days. +/// For discussion / rationale, see https://forum.arbitrum.foundation/t/rfc-constitutional-aip-security-council-improvement-proposal/20541 +contract AIPIncreaseCoreTimelockDelayAction is UpdateCoreTimelockDelayAction { + constructor() + UpdateCoreTimelockDelayAction( + ICoreGovTimelockGetter(0x56C4E9Eb6c63aCDD19AeC2b1a00e4f0d7aBda9d3), + 8 days + ) + {} +} diff --git a/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPIncreaseNonEmergencySCThresholdAction.sol b/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPIncreaseNonEmergencySCThresholdAction.sol new file mode 100644 index 000000000..71cee407d --- /dev/null +++ b/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPIncreaseNonEmergencySCThresholdAction.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.16; + +import "../../governance/SetSCThresholdAction.sol"; + +///@notice increase the non-emergency Security Council Threshold from 7 to 9. +/// For discussion / rationale, see https://forum.arbitrum.foundation/t/rfc-constitutional-aip-security-council-improvement-proposal/20541 +contract AIPIncreaseNonEmergencySCThresholdAction is SetSCThresholdAction { + constructor() + SetSCThresholdAction(IGnosisSafe(0xADd68bCb0f66878aB9D37a447C7b9067C5dfa941), 7, 9) + {} +} diff --git a/src/gov-action-contracts/governance/SetSCThresholdAction.sol b/src/gov-action-contracts/governance/SetSCThresholdAction.sol new file mode 100644 index 000000000..83a97cdd0 --- /dev/null +++ b/src/gov-action-contracts/governance/SetSCThresholdAction.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.16; + +interface IGnosisSafe { + function getThreshold() external view returns (uint256); + function changeThreshold(uint256 _threshold) external; +} + +///@notice Set the minimum signing threshold for a security council gnosis safe. Assumes that the safe has the UpgradeExecutor added as a module. +contract SetSCThresholdAction { + IGnosisSafe public immutable gnosisSafe; + uint256 public immutable oldThreshold; + uint256 public immutable newThreshold; + + constructor(IGnosisSafe _gnosisSafe, uint256 _oldThreshold, uint256 _newThreshold) { + gnosisSafe = _gnosisSafe; + oldThreshold = _oldThreshold; + newThreshold = _newThreshold; + } + + function perform() external { + // sanity check old threshold + require( + gnosisSafe.getThreshold() == oldThreshold, "SecSCThresholdAction: WRONG_OLD_THRESHOLD" + ); + + gnosisSafe.changeThreshold(newThreshold); + // sanity check new threshold was set + require( + gnosisSafe.getThreshold() == newThreshold, "SecSCThresholdAction: NEW_THRESHOLD_NOT_SET" + ); + } +} diff --git a/src/gov-action-contracts/governance/UpdateCoreTimelockDelayAction.sol b/src/gov-action-contracts/governance/UpdateCoreTimelockDelayAction.sol new file mode 100644 index 000000000..cb2f913e9 --- /dev/null +++ b/src/gov-action-contracts/governance/UpdateCoreTimelockDelayAction.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.16; + +import "../address-registries/L2AddressRegistry.sol"; + +///@notice Update core timelock delay — the minimum amount of time after a passed-proposal is queued before it can be executed. +contract UpdateCoreTimelockDelayAction { + IArbitrumTimelock public immutable timelock; + uint256 public immutable newDelay; + + constructor(ICoreGovTimelockGetter _l2AddressRegistry, uint256 _newDelay) { + timelock = _l2AddressRegistry.coreGovTimelock(); + newDelay = _newDelay; + } + + function perform() external { + timelock.updateDelay(newDelay); + // sanity check: + require(timelock.getMinDelay() == newDelay, "UpdateTimelockDelayAction: DELAY_NOT_SET"); + } +} From 86410f81194163afe82768595462ec632706219b Mon Sep 17 00:00:00 2001 From: dzgoldman Date: Thu, 11 Jan 2024 13:39:39 -0500 Subject: [PATCH 2/4] add non-emergency council removal action --- .../AIPRemoveNonEmergencySCAction.sol | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/gov-action-contracts/AIPs/SCImprovementAIP/AIPRemoveNonEmergencySCAction.sol diff --git a/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPRemoveNonEmergencySCAction.sol b/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPRemoveNonEmergencySCAction.sol new file mode 100644 index 000000000..29a820cd8 --- /dev/null +++ b/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPRemoveNonEmergencySCAction.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.16; + +import "../../../security-council-mgmt/interfaces/ISecurityCouncilManager.sol"; +import "../../../interfaces/ICoreTimelock.sol"; + +///@notice Effectively "remove" the non emergency security council; prevent it from proposing in the timelock and don't update it in security council elections +contract AIPRemoveNonEmergencySCAction { + ISecurityCouncilManager public constant securityCouncilManager = + ISecurityCouncilManager(0xD509E5f5aEe2A205F554f36E8a7d56094494eDFC); + ICoreTimelock public constant timelock = + ICoreTimelock(0x34d45e99f7D8c45ed05B5cA72D54bbD1fb3F98f0); + address nonEmergecySC = 0xADd68bCb0f66878aB9D37a447C7b9067C5dfa941; + + function perform() external { + // revoke SC's role on timelock + timelock.revokeRole(timelock.PROPOSER_ROLE(), nonEmergecySC); + + // remove SC from elections + securityCouncilManager.removeSecurityCouncil( + SecurityCouncilData({ + securityCouncil: nonEmergecySC, + updateAction: 0x9BF7b8884Fa381a45f8CB2525905fb36C996297a, + chainId: 42_161 + }) + ); + } +} From cae969f822862d3bc0e25fc32ad3f2bff47d2a4c Mon Sep 17 00:00:00 2001 From: dzgoldman Date: Thu, 11 Jan 2024 15:01:11 -0500 Subject: [PATCH 3/4] fix SetSCThresholdAction; use module --- .../governance/SetSCThresholdAction.sol | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gov-action-contracts/governance/SetSCThresholdAction.sol b/src/gov-action-contracts/governance/SetSCThresholdAction.sol index 83a97cdd0..c13287f92 100644 --- a/src/gov-action-contracts/governance/SetSCThresholdAction.sol +++ b/src/gov-action-contracts/governance/SetSCThresholdAction.sol @@ -1,8 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.16; -interface IGnosisSafe { - function getThreshold() external view returns (uint256); +import "../../security-council-mgmt/interfaces/IGnosisSafe.sol"; + +interface _IGnosisSafe { function changeThreshold(uint256 _threshold) external; } @@ -24,7 +25,12 @@ contract SetSCThresholdAction { gnosisSafe.getThreshold() == oldThreshold, "SecSCThresholdAction: WRONG_OLD_THRESHOLD" ); - gnosisSafe.changeThreshold(newThreshold); + gnosisSafe.execTransactionFromModule({ + to: address(gnosisSafe), + value: 0, + data: abi.encodeWithSelector(_IGnosisSafe.changeThreshold.selector, newThreshold), + operation: OpEnum.Operation.Call + }); // sanity check new threshold was set require( gnosisSafe.getThreshold() == newThreshold, "SecSCThresholdAction: NEW_THRESHOLD_NOT_SET" From ce429867cc8fb6ec9fbbe3057400ccde3f4fdefd Mon Sep 17 00:00:00 2001 From: dzgoldman Date: Thu, 11 Jan 2024 15:02:40 -0500 Subject: [PATCH 4/4] add comment --- .../AIPs/SCImprovementAIP/AIPRemoveNonEmergencySCAction.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPRemoveNonEmergencySCAction.sol b/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPRemoveNonEmergencySCAction.sol index 29a820cd8..42a785bcb 100644 --- a/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPRemoveNonEmergencySCAction.sol +++ b/src/gov-action-contracts/AIPs/SCImprovementAIP/AIPRemoveNonEmergencySCAction.sol @@ -5,6 +5,7 @@ import "../../../security-council-mgmt/interfaces/ISecurityCouncilManager.sol"; import "../../../interfaces/ICoreTimelock.sol"; ///@notice Effectively "remove" the non emergency security council; prevent it from proposing in the timelock and don't update it in security council elections +/// For discussion / rationale, see https://forum.arbitrum.foundation/t/rfc-constitutional-aip-security-council-improvement-proposal/20541 contract AIPRemoveNonEmergencySCAction { ISecurityCouncilManager public constant securityCouncilManager = ISecurityCouncilManager(0xD509E5f5aEe2A205F554f36E8a7d56094494eDFC);