Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions scripts/proposals/AIPSCThreshold/data/AIPSCThreshold-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"actionChainID": [
42161
],
"actionAddress": [
"0x25afB879bb5364cB3f7e0b607AD280C0F52B0D82"
],
"description": "\n### **Abstract**\n\nThis AIP seeks to propose changes to the structure of the security council so Arbitrum can maintain the “Stage 1” designation as per L2BEAT and not fall back to “Stage 0” designation.\n\n### **Motivation**\n\nOn December 7, [L2BEAT published an update](https://medium.com/l2beat/stages-update-security-council-requirements-4c79cea8ef52) to the security council requirements for the [Stages Framework](https://medium.com/l2beat/introducing-stages-a-framework-to-evaluate-rollups-maturity-d290bb22befe). The requirements were updated after a lot of research and feedback to make Stages more formal and precise. \n\n### **Rationale**\n\nUpgrading the security council as per the Stage 1 requirements set by L2BEAT, will help ensure Arbitrum remains decentralized, but properly secured. See ‘Specifications’ for more details.\n\n### **Key Terms**\n\n**Stages:** A framework, inspired by [Vitalik’s proposed milestones](https://ethereum-magicians.org/t/proposed-milestones-for-rollups-taking-off-training-wheels/11571), that categorises rollups into three distinct stages based on their reliance on these training wheels. You can learn [more about the Stages framework here](https://medium.com/l2beat/introducing-stages-a-framework-to-evaluate-rollups-maturity-d290bb22befe).\n\n**Security Council:** A group of 12 individuals who are responsible for addressing risks to the Arbitrum ecosystem through the selective application of **e**mergency actions and non-emergency actions. Learn more in [the ArbitrumDAO Docs](https://docs.arbitrum.foundation/concepts/security-council).\n\n**Timelock:** Smart contracts which implement a delay between an upgrade confirmation and execution.\n\n**Exit Window:** The actual time users have to exit the system in case of an unwanted upgrade.\n\n### **Specifications**\n\nArbitrum currently has two multisigs and they both contain the same set of members:\n\na) A 9/12 multisig with instant upgrade power \n\nb) A 7/12 multisig that can upgrade with a 3+7+3 days delay \n\nWhile the higher threshold multisig can be classified as a Security Council, the lower one is below the minimum threshold and it’s considered a simple multisig according to the Stages framework introduced above.\n\nFor normal multisigs, L2BEAT requires at least a 7 days exit window for users. The current exit window for Arbitrum is 2 days (see [this thread](https://x.com/stonecoldpat0/status/1737840485967032739?s=20) for a quick explanation).\n\nMoreover, the higher threshold multisig is supposed to stop malicious upgrades attempted by the lower threshold multisig. However, since the member set is the same, if the lower threshold agrees on something there are not enough members in the higher threshold to stop them, which means that the actual security of the upgradeability mechanism boils down to the 7/12 threshold.\n\nFor the above reason, technically, with the updated requirements for Stages, Arbitrum falls back to the Stage 0 designation. Since we know that it takes time to upgrade Arbitrum, we decided to leave the Stage 1 designation with the promise of addressing the above issues in a timely manner. This proposal is about addressing the issues and moving them to be voted on by the DAO.\n\n**Proposed Solutions**\n\n1) The **first solution** would be to remove the lower threshold (7/12) multisig entirely. This can be done in two ways:\n* The contract is removed which requires an on-chain upgrade, or,\n* The lower threshold multisig increases its threshold from 7/12 to 9/12 which requires no upgrade.\n \nIncreasing the threshold gives us the flexibility to restore a lower threshold in the future should the need arise, and it’s also a very quick and easy fix since it doesn’t require an on-chain upgrade.\n \nOn the other hand, removing the dependency on the lower threshold mutlisig for all the contracts in Arbitrum is a broad and potentially risky change. Therefore we suggest raising the threshold for the time being and revisiting the removal of all the dependencies at a later date if needed.\n\n2) The **second solution** would be to leave the lower threshold multisig as it is, but to increase the exit window to 7 days. In practice, this involves increasing the L2 timelock delay from 3 days to 8 days, since there is a 1 day max delay to force transactions on Arbitrum via L1 using the ‘DelayedInbox’. Increasing the L1 Timelock would not be very beneficial due to delay attacks on the fraud proof systems, since, even with BoLD, the challenge period would end up being up to [16 days](https://x.com/DZack23/status/1737864854059335905?s=20).\n\n3) The ****************************third solution****************************, which is not strictly required by the Stages Framework for the Stage 1 designation, is to both remove the lower threshold multisig entirely and increase the L2 Timelock delay so users have more time to exit in case of unwanted upgrades, increasing the security of the system even more.\n\n### Steps to Implement\n\nFollowing a week of discussion of this RFC, the proposal will go for a vote on Snapshot with the following 4 options (as they are or slightly adjusted), and/or any additional ones, should they arise from the discussion during the RFC phase:\n\n1. Increase the threshold from 7/12 to 9/12.\n2. Increase the L2 timelock delay from 3 days to 8 days.\n3. Increase the threshold and the L2 timelock delay.\n4. Make no changes.\n\nFollowing the temp-check, if any of the aforementioned options apart from No.4 is the most popular, the proposal will move to on-chain vote to execute the proposal.\n\n### **Overall Cost**\n\nThere’s no overhead to the DAO for the implementation of this proposal.\n",
"arbSysSendTxToL1Args": {
"l1Timelock": "0xE6841D92B0C345144506576eC13ECf5103aC7f49",
"calldata": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000f081971a6bbfc9246db73cab798cd1344571aba50e5b99e47c9830f4bd015080000000000000000000000000000000000000000000000000000000000003f4800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a723c008e76e379c55599d2e4d93879beafda79c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001800000000000000000000000004dbd4fc535ac27206064b68ffcf827b0a60bab3f000000000000000000000000cf57572261c7c2bcf21ffd220ea7d1a27d40a82700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000841cff79cd00000000000000000000000025afb879bb5364cb3f7e0b607ad280c0f52b0d8200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000004b147f40c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
}
}
67 changes: 67 additions & 0 deletions scripts/proposals/AIPSCThreshold/description.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

### **Abstract**

This AIP seeks to propose changes to the structure of the security council so Arbitrum can maintain the “Stage 1” designation as per L2BEAT and not fall back to “Stage 0” designation.

### **Motivation**

On December 7, [L2BEAT published an update](https://medium.com/l2beat/stages-update-security-council-requirements-4c79cea8ef52) to the security council requirements for the [Stages Framework](https://medium.com/l2beat/introducing-stages-a-framework-to-evaluate-rollups-maturity-d290bb22befe). The requirements were updated after a lot of research and feedback to make Stages more formal and precise.

### **Rationale**

Upgrading the security council as per the Stage 1 requirements set by L2BEAT, will help ensure Arbitrum remains decentralized, but properly secured. See ‘Specifications’ for more details.

### **Key Terms**

**Stages:** A framework, inspired by [Vitalik’s proposed milestones](https://ethereum-magicians.org/t/proposed-milestones-for-rollups-taking-off-training-wheels/11571), that categorises rollups into three distinct stages based on their reliance on these training wheels. You can learn [more about the Stages framework here](https://medium.com/l2beat/introducing-stages-a-framework-to-evaluate-rollups-maturity-d290bb22befe).

**Security Council:** A group of 12 individuals who are responsible for addressing risks to the Arbitrum ecosystem through the selective application of **e**mergency actions and non-emergency actions. Learn more in [the ArbitrumDAO Docs](https://docs.arbitrum.foundation/concepts/security-council).

**Timelock:** Smart contracts which implement a delay between an upgrade confirmation and execution.

**Exit Window:** The actual time users have to exit the system in case of an unwanted upgrade.

### **Specifications**

Arbitrum currently has two multisigs and they both contain the same set of members:

a) A 9/12 multisig with instant upgrade power

b) A 7/12 multisig that can upgrade with a 3+7+3 days delay

While the higher threshold multisig can be classified as a Security Council, the lower one is below the minimum threshold and it’s considered a simple multisig according to the Stages framework introduced above.

For normal multisigs, L2BEAT requires at least a 7 days exit window for users. The current exit window for Arbitrum is 2 days (see [this thread](https://x.com/stonecoldpat0/status/1737840485967032739?s=20) for a quick explanation).

Moreover, the higher threshold multisig is supposed to stop malicious upgrades attempted by the lower threshold multisig. However, since the member set is the same, if the lower threshold agrees on something there are not enough members in the higher threshold to stop them, which means that the actual security of the upgradeability mechanism boils down to the 7/12 threshold.

For the above reason, technically, with the updated requirements for Stages, Arbitrum falls back to the Stage 0 designation. Since we know that it takes time to upgrade Arbitrum, we decided to leave the Stage 1 designation with the promise of addressing the above issues in a timely manner. This proposal is about addressing the issues and moving them to be voted on by the DAO.

**Proposed Solutions**

1) The **first solution** would be to remove the lower threshold (7/12) multisig entirely. This can be done in two ways:
* The contract is removed which requires an on-chain upgrade, or,
* The lower threshold multisig increases its threshold from 7/12 to 9/12 which requires no upgrade.
 
Increasing the threshold gives us the flexibility to restore a lower threshold in the future should the need arise, and it’s also a very quick and easy fix since it doesn’t require an on-chain upgrade.
 
On the other hand, removing the dependency on the lower threshold mutlisig for all the contracts in Arbitrum is a broad and potentially risky change. Therefore we suggest raising the threshold for the time being and revisiting the removal of all the dependencies at a later date if needed.

2) The **second solution** would be to leave the lower threshold multisig as it is, but to increase the exit window to 7 days. In practice, this involves increasing the L2 timelock delay from 3 days to 8 days, since there is a 1 day max delay to force transactions on Arbitrum via L1 using the ‘DelayedInbox’. Increasing the L1 Timelock would not be very beneficial due to delay attacks on the fraud proof systems, since, even with BoLD, the challenge period would end up being up to [16 days](https://x.com/DZack23/status/1737864854059335905?s=20).

3) The ****************************third solution****************************, which is not strictly required by the Stages Framework for the Stage 1 designation, is to both remove the lower threshold multisig entirely and increase the L2 Timelock delay so users have more time to exit in case of unwanted upgrades, increasing the security of the system even more.

### Steps to Implement

Following a week of discussion of this RFC, the proposal will go for a vote on Snapshot with the following 4 options (as they are or slightly adjusted), and/or any additional ones, should they arise from the discussion during the RFC phase:

1. Increase the threshold from 7/12 to 9/12.
2. Increase the L2 timelock delay from 3 days to 8 days.
3. Increase the threshold and the L2 timelock delay.
4. Make no changes.

Following the temp-check, if any of the aforementioned options apart from No.4 is the most popular, the proposal will move to on-chain vote to execute the proposal.

### **Overall Cost**

There’s no overhead to the DAO for the implementation of this proposal.
76 changes: 76 additions & 0 deletions scripts/proposals/AIPSCThreshold/generateProposalData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { RoundTripProposalCreator } from "../../../src-ts/proposalCreator";
import { JsonRpcProvider } from "@ethersproject/providers";
import { constants, utils } from "ethers";
import { CoreGovPropposal } from "../coreGovProposalInterface";
import dotenv from "dotenv";
import { importDeployedContracts } from "../../../src-ts/utils";
import fs from "fs";
const zero = constants.Zero;
dotenv.config();

const mainnetDeployedContracts = importDeployedContracts("./files/mainnet/deployedContracts.json");

dotenv.config();

const description = fs.readFileSync("./scripts/proposals/AIPSCThreshold/description.txt").toString()

if(!process.env.ETH_URL) throw new Error("no eth rpc")
if(!process.env.ARB_URL) throw new Error("no arb1 rpc")

const l1Provider = new JsonRpcProvider(process.env.ETH_URL);
const govChainProvider = new JsonRpcProvider(process.env.ARB_URL);

const l1GovConfig = {
timelockAddr: mainnetDeployedContracts.l1Timelock,
provider: l1Provider,
};

if (!mainnetDeployedContracts.novaUpgradeExecutorProxy)
throw new Error("novaUpgradeExecutorProxy not found");
const upgradeExecs = [
{
upgradeExecutorAddr: mainnetDeployedContracts.l2Executor,
provider: govChainProvider,
},
];

const actionAddresses = [
"0x25afB879bb5364cB3f7e0b607AD280C0F52B0D82",
];

const performEncoded = new utils.Interface(["function perform() external"]).encodeFunctionData(
"perform",
[]
);

const values = actionAddresses.map(() => zero);
const datas = actionAddresses.map(() => performEncoded);

const main = async () => {
const propCreator = new RoundTripProposalCreator(l1GovConfig, upgradeExecs);

const res = await propCreator.createRoundTripCallDataForArbSysCall(
actionAddresses,
values,
datas,
description
);

const proposal: CoreGovPropposal = {
actionChainID: [42161],
actionAddress: actionAddresses,
description,
arbSysSendTxToL1Args: {
l1Timelock: mainnetDeployedContracts.l1Timelock,
calldata: res.l1TimelockScheduleCallData,
},
};

const path = `${__dirname}/data/AIPSCThreshold-data.json`;
fs.writeFileSync(path, JSON.stringify(proposal, null, 2));
console.log("Wrote proposal data to", path);
};

main().then(() => {
console.log("done");
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.16;

import "../../governance/SetSCThresholdAndUpdateConstitutionAction.sol";
import "../../../interfaces/IArbitrumDAOConstitution.sol";

///@notice increase the non-emergency Security Council Threshold from 7 to 9 and update constitution accordingly.
/// For discussion / rationale, see https://forum.arbitrum.foundation/t/rfc-constitutional-aip-security-council-improvement-proposal/20541
/// Old constitution hash comes from election propoosal, see https://forum.arbitrum.foundation/t/aip-changes-to-the-constitution-and-the-security-council-election-process/20856/13
contract AIPIncreaseNonEmergencySCThresholdAction is SetSCThresholdAndUpdateConstitutionAction {
constructor()
SetSCThresholdAndUpdateConstitutionAction(
IGnosisSafe(0xADd68bCb0f66878aB9D37a447C7b9067C5dfa941), // non emergency security council
7, // old threshold
9, // new threshold
IArbitrumDAOConstitution(address(0x1D62fFeB72e4c360CcBbacf7c965153b00260417)), // DAO constitution
bytes32(0xe794b7d0466ffd4a33321ea14c307b2de987c3229cf858727052a6f4b8a19cc1), // constitution hash: election change, no threshold increase. https://github.com/ArbitrumFoundation/docs/tree/0837520dccc12e56a25f62de90ff9e3869196d05
bytes32(0x7cc34e90dde73cfe0b4a041e79b5638e99f0d9547001e42b466c32a18ed6789d) // constitution hash: election change abd threshold increase. https://github.com/ArbitrumFoundation/docs/pull/762/commits/88a6d38e15f1691c2ce7d31fe7c21e8fd52ac126
)
{}
}
47 changes: 47 additions & 0 deletions src/gov-action-contracts/governance/ConstitutionActionLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.16;

import "../../interfaces/IArbitrumDAOConstitution.sol";

library ConstitutionActionLib {
error ConstitutionHashNotSet();
error UnhandledConstitutionHash();
error ConstitutionHashLengthMismatch();

/// @notice Update dao constitution hash
/// @param constitution DAO constitution contract
/// @param _newConstitutionHash new constitution hash
function updateConstitutionHash(
IArbitrumDAOConstitution constitution,
bytes32 _newConstitutionHash
) internal {
constitution.setConstitutionHash(_newConstitutionHash);
if (constitution.constitutionHash() != _newConstitutionHash) {
revert ConstitutionHashNotSet();
}
}

/// @notice checks actual constitution hash for presence in _oldConstitutionHashes and sets constitution hash to the hash in the corresponding index in _newConstitutionHashes if found
/// @param _constitution DAO constitution contract
/// @param _oldConstitutionHashes hashes to check against the current constitution
/// @param _newConstitutionHashes hashes to set at corresponding index if hash in oldConstitutionHashes is found (on the first match)
function conditonallyUpdateConstitutionHash(
IArbitrumDAOConstitution _constitution,
bytes32[] memory _oldConstitutionHashes,
bytes32[] memory _newConstitutionHashes
) internal returns (bytes32) {
bytes32 constitutionHash = _constitution.constitutionHash();
if (_oldConstitutionHashes.length != _newConstitutionHashes.length) {
revert ConstitutionHashLengthMismatch();
}

for (uint256 i = 0; i < _oldConstitutionHashes.length; i++) {
if (_oldConstitutionHashes[i] == constitutionHash) {
bytes32 newConstitutionHash = _newConstitutionHashes[i];
updateConstitutionHash(_constitution, newConstitutionHash);
return newConstitutionHash;
}
}
revert UnhandledConstitutionHash();
}
}
Loading