Skip to content

Commit

Permalink
Merge branch 'main' into extra-contender-phase
Browse files Browse the repository at this point in the history
  • Loading branch information
DZGoldman committed Jan 24, 2024
2 parents 968dfd3 + d197468 commit 06693a7
Show file tree
Hide file tree
Showing 32 changed files with 549 additions and 40 deletions.
16 changes: 8 additions & 8 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ L1ArbitrumTokenTest:testInitZeroNovaGateway() (gas: 3177301)
L1ArbitrumTokenTest:testInitZeroNovaRouter() (gas: 3177235)
L1ArbitrumTokenTest:testRegisterTokenOnL2() (gas: 4568612)
L1ArbitrumTokenTest:testRegisterTokenOnL2NotEnoughVal() (gas: 4425799)
L1GovernanceFactoryTest:testL1GovernanceFactory() (gas: 10771117)
L1GovernanceFactoryTest:testL1GovernanceFactory() (gas: 10771109)
L1GovernanceFactoryTest:testSetMinDelay() (gas: 10746003)
L1GovernanceFactoryTest:testSetMinDelayRevertsForCoreAddress() (gas: 10798958)
L2AddressRegistryTest:testAddressRegistryAddress() (gas: 54658)
Expand Down Expand Up @@ -99,11 +99,11 @@ L2SecurityCouncilMgmtFactoryTest:testOnlyOwnerCanDeploy() (gas: 25659644)
L2SecurityCouncilMgmtFactoryTest:testRemovalGovDeployment() (gas: 30526232)
L2SecurityCouncilMgmtFactoryTest:testSecurityCouncilManagerDeployment() (gas: 30545325)
NomineeGovernorV2UpgradeActionTest:testAction() (gas: 8153)
OutboxActionsTest:testAddOutbxesAction() (gas: 651591)
OutboxActionsTest:testCantAddEOA() (gas: 969161)
OutboxActionsTest:testCantReAddOutbox() (gas: 974559)
OutboxActionsTest:testRemoveAllOutboxes() (gas: 693238)
OutboxActionsTest:testRemoveOutboxes() (gas: 854205)
OutboxActionsTest:testAddOutbxesAction() (gas: 651420)
OutboxActionsTest:testCantAddEOA() (gas: 968990)
OutboxActionsTest:testCantReAddOutbox() (gas: 974388)
OutboxActionsTest:testRemoveAllOutboxes() (gas: 692972)
OutboxActionsTest:testRemoveOutboxes() (gas: 853926)
ProxyUpgradeAndCallActionTest:testUpgrade() (gas: 137095)
ProxyUpgradeAndCallActionTest:testUpgradeAndCall() (gas: 143042)
SecurityCouncilManagerTest:testAddMemberAffordances() (gas: 249651)
Expand Down Expand Up @@ -143,7 +143,7 @@ SecurityCouncilMemberElectionGovernorTest:testOnlyNomineeElectionGovernorCanProp
SecurityCouncilMemberElectionGovernorTest:testProperInitialization() (gas: 49388)
SecurityCouncilMemberElectionGovernorTest:testProposeReverts() (gas: 32916)
SecurityCouncilMemberElectionGovernorTest:testRelay() (gas: 42229)
SecurityCouncilMemberElectionGovernorTest:testSelectTopNominees(uint256) (runs: 256, μ: 339963, ~: 339326)
SecurityCouncilMemberElectionGovernorTest:testSelectTopNominees(uint256) (runs: 256, μ: 339959, ~: 339349)
SecurityCouncilMemberElectionGovernorTest:testSelectTopNomineesFails() (gas: 273335)
SecurityCouncilMemberElectionGovernorTest:testSetFullWeightDuration() (gas: 34951)
SecurityCouncilMemberElectionGovernorTest:testVotesToWeight() (gas: 152898)
Expand Down Expand Up @@ -192,7 +192,7 @@ SecurityCouncilNomineeElectionGovernorTest:testProperInitialization() (gas: 7811
SecurityCouncilNomineeElectionGovernorTest:testProposeFails() (gas: 19740)
SecurityCouncilNomineeElectionGovernorTest:testRelay() (gas: 42427)
SecurityCouncilNomineeElectionGovernorTest:testSetNomineeVetter() (gas: 39905)
SequencerActionsTest:testAddAndRemoveSequencer() (gas: 483356)
SequencerActionsTest:testAddAndRemoveSequencer() (gas: 483444)
SequencerActionsTest:testCantAddZeroAddress() (gas: 235614)
SetInitialGovParamsActionTest:testL1() (gas: 259904)
SetInitialGovParamsActionTest:testL2() (gas: 688888)
Expand Down
4 changes: 3 additions & 1 deletion audit-ci.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
// get-func-name - only used in chai, not used in prod
"GHSA-4q6p-r6v2-jvc5",
// axios used only in sol2uml
"GHSA-wf5p-g6vw-rhxx"
"GHSA-wf5p-g6vw-rhxx",
// follow-redirects url.parse bug. Not used in prod
"GHSA-jchw-25xp-jwwc"
]
}
Binary file not shown.
4 changes: 3 additions & 1 deletion docs/gotchas.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ An operation queued in the core-governor-timelock or the treasury-governor-timel
There are two L1 proxy admins - one for the governance contracts, once for the governed core Nitro contracts. Note that both proxy admins have the same owner (the DAO), and thus this has no material effect on the DAO's affordances.

- **Non-excluded L2 Timelock**
ARB in the both treasury timelock and the DAO treasury can be transferred via treasury gov DAO vote; however, only ARB in the DAO treasury is excluded from the quorum numerator calculation. Thus, the DAO’s ARB should ideally all be stored in the DAO Treasury.
ARB in both the treasury timelock and the DAO treasury can be transferred via treasury gov DAO vote; however, only ARB in the DAO treasury is excluded from the quorum numerator calculation. Thus, the DAO’s ARB should ideally all be stored in the DAO Treasury.

- **L2ArbitrumGovernoer onlyGovernance behavior**
Typically, for a timelocked OZ governror, the `onlyGovernance` modifier ensures a call is made from the timelock; in L2ArbitrumGoverner, the _executor() method is overriden such that `onlyGovernance` enforces a call from the governor contract itself. This ensures calls guarded by `onlyGovernance` go through the full core proposal path, as calls from the governor could only be sent via `relay`. See the code comment on `relay` in [L2ArbitrumGoveror](../src/L2ArbitrumGovernor.sol) for more.
Expand All @@ -28,5 +28,7 @@ Typically, for a timelocked OZ governror, the `onlyGovernance` modifier ensures
- Changes to members of the Security Council should be initiated via the SecurityCouncilManager, not via calling addOwner/removeOwner on the multisigs directly. This ensures that the security council's two cohorts remain properly tracked in the SecurityCouncilManager contract.

- **UpgradeExecutor Affordance**

Affordances are always given to the DAO via an UpgradeExecutor contract, which grants affordance to both the core governor proposal path and the Security Council. This includes abilities that are intended only for the Security Council; for example, proposal cancellation, practically speaking, could/would only ever be preformed by the Security Council (since the DAO wouldn't have time to vote on and execute a cancellation). Still, for this case, the affordance is given to the UpgradeExecutor; this is done for clarity, consistency, and to ensure that the UpgradeExecutor is the single source of truth for execution rights.

The only affordances granted directly to the Security Council (and not to its corresponding UpradeExecutor) are the "MEMBER_ADDER", "MEMBER_REPLACER", "MEMBER_ROTATOR", and "MEMBER_REMOVER" roles on the SecurityCouncilManager contract. If the emergency Security Council on Arbitrum One is ever either removed or deployed to a new address, these roles should be modified accordingly.
3 changes: 2 additions & 1 deletion files/mainnet/deployedContracts.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@
"l1ProxyAdmin": "0x5613AF0474EB9c528A34701A5b1662E3C8FA0678",
"l1Timelock": "0xE6841D92B0C345144506576eC13ECf5103aC7f49",
"l1AddressRegistry": "0xd514C2b3aaBDBfa10800B9C96dc1eB25427520A0",
"l2AddressRegistry":"0x56C4E9Eb6c63aCDD19AeC2b1a00e4f0d7aBda9d3"
"l2AddressRegistry":"0x56C4E9Eb6c63aCDD19AeC2b1a00e4f0d7aBda9d3",
"novaL1AddressRegistry":"0x2F06643fc2CC18585Ae790b546388F0DE4Ec6635"
}
9 changes: 7 additions & 2 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@nomicfoundation/hardhat-foundry";

import dotenv from "dotenv";
dotenv.config();
// when changing optimizer settings, make sure to also change settings in foundry.toml
const solidityProfiles = {
default: {
Expand All @@ -24,8 +25,12 @@ const solidityProfiles = {
}
}

const solidity = solidityProfiles[process.env.FOUNDRY_PROFILE || "default"] || solidityProfiles.default
console.log("Compiling with soldity profile:", solidity);


const config: HardhatUserConfig = {
solidity: solidityProfiles[process.env.FOUNDRY_PROFILE || "default"] || solidityProfiles.default,
solidity,
paths: {
sources: "./src",
tests: "./test-ts",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"typescript": "^4.8.4"
},
"dependencies": {
"@arbitrum/nitro-contracts": "1.0.1",
"@arbitrum/nitro-contracts": "1.0.3-beta.0",
"@arbitrum/token-bridge-contracts": "1.0.0-beta.0",
"@gnosis.pm/safe-contracts": "1.3.0",
"@openzeppelin/contracts": "4.7.3",
Expand Down
90 changes: 90 additions & 0 deletions scripts/checkAccessControlRoles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { IAccessControlUpgradeable__factory } from "../typechain-types";
import { keccak256, toUtf8Bytes } from "ethers/lib/utils";
import { Provider, JsonRpcProvider } from "@ethersproject/providers";

import { RoleGrantedEventObject } from "../typechain-types/@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable";

interface RolesToRolePreimages {
[key: string]: string;
}

interface RolesToAccounts {
[key: string]: Set<string>;
}

const rolesPreimages = [
"TIMELOCK_ADMIN_ROLE",
"PROPOSER_ROLE",
"EXECUTOR_ROLE",
"CANCELLER_ROLE",
"ADMIN_ROLE",
"COHORT_REPLACER",
"MEMBER_ADDER",
"MEMBER_REPLACER",
"MEMBER_ROTATOR",
"MEMBER_REMOVER",
];
const rolesToRolePreimages: RolesToRolePreimages = {};
rolesPreimages.forEach((roleStr: string) => {
rolesToRolePreimages[keccak256(toUtf8Bytes(roleStr))] = roleStr;
});

export const getCurrentRoles = async (
rpcProvider: Provider,
contractAddr: string,
displayName: string,
fromBlock = 0,
verbose = true
) => {
const network = await rpcProvider.getNetwork();
if (verbose) {
console.log(`Checking roles for ${contractAddr} "${displayName}" on chain ${network.chainId}`);
}

const accessControlContract = IAccessControlUpgradeable__factory.connect(
contractAddr,
rpcProvider
);
const filterTopics = accessControlContract.interface.encodeFilterTopics("RoleGranted", []);

const roleGrantedLogsRaw = await rpcProvider.getLogs({
fromBlock,
topics: filterTopics,
address: contractAddr,
});

const roleGrantedLogs = roleGrantedLogsRaw.map((log) => {
const parsedLog = accessControlContract.interface.parseLog(log);
return parsedLog.args as unknown as RoleGrantedEventObject;
});

const rolesToAccounts: RolesToAccounts = {};
for (let roleGrantedLog of roleGrantedLogs) {
const { role, account } = roleGrantedLog;

if (!(await accessControlContract.hasRole(role, account))) {
continue;
}

if (rolesToAccounts[role]) {
rolesToAccounts[role].add(account);
} else {
rolesToAccounts[role] = new Set([account]);
}
}
if (verbose) {
for (let roleHash of Object.keys(rolesToAccounts)) {
const roleToDisplay = rolesToRolePreimages[roleHash]
? rolesToRolePreimages[roleHash]
: roleHash;
console.log("");
console.log(`Accounts with '${roleToDisplay}':`);
for (let account of rolesToAccounts[roleHash]) {
console.log(account);
}
}
console.log("");
console.log("");
}
return rolesToAccounts;
};
52 changes: 52 additions & 0 deletions scripts/deployNovaAddressRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Wallet } from "@ethersproject/wallet";
import { JsonRpcProvider } from "@ethersproject/providers";
import { L1AddressRegistry__factory } from "../typechain-types";

import { ContractVerifier } from "./contractVerifier";
import dotenv from "dotenv";
import { utils } from "ethers";
const abi = utils.defaultAbiCoder;

dotenv.config();

const ETH_URL = process.env.ETH_URL;
const ETH_KEY = process.env.ETH_KEY;
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY;

if (!ETH_URL) throw new Error("ETH_URL required");
if (!ETH_KEY) throw new Error("ETH_KEY required");
if (!ETHERSCAN_API_KEY) throw new Error("ETHERSCAN_API_KEY required");

const main = async () => {
const l1Provider = new JsonRpcProvider(ETH_URL);
const signer = new Wallet(ETH_KEY, l1Provider);

const l1Verifier = new ContractVerifier(1, ETHERSCAN_API_KEY, {});

const NOVA_INBOX = "0xc4448b71118c9071Bcb9734A0EAc55D18A153949";
const L1_GOV_TIMELOCK = "0xE6841D92B0C345144506576eC13ECf5103aC7f49";
const NOVA_L1_CUSTOM_GATEWAY = "0x23122da8C581AA7E0d07A36Ff1f16F799650232f";
const NOVA_L1_GATEWAY_ROUTER = "0xC840838Bc438d73C16c2f8b22D2Ce3669963cD48";

const novaL1AddressRegistry = await new L1AddressRegistry__factory(signer).deploy(
NOVA_INBOX, // nova inbox
L1_GOV_TIMELOCK, // l1 gov timelock
NOVA_L1_CUSTOM_GATEWAY, // nova l1 custom gateway
NOVA_L1_GATEWAY_ROUTER // nova l1 gateway router
);
await novaL1AddressRegistry.deployed();
console.log("L1AddressRegistry deployed at", novaL1AddressRegistry.address);

await l1Verifier.verifyWithAddress(
"L1AddressRegistry",
novaL1AddressRegistry.address,
abi.encode(
["address", "address", "address", "address"],
[NOVA_INBOX, L1_GOV_TIMELOCK, NOVA_L1_CUSTOM_GATEWAY, NOVA_L1_GATEWAY_ROUTER]
)
);
};

main().then(() => {
console.log("Done");
});
21 changes: 21 additions & 0 deletions scripts/printAccessControlRoles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { JsonRpcProvider } from "@ethersproject/providers";
import dotenv from "dotenv";
import { getCurrentRoles } from "./checkAccessControlRoles";
dotenv.config();

(async () => {
const ethRpc = new JsonRpcProvider(process.env.ETH_URL);

const arbOneRpc = new JsonRpcProvider(process.env.ARB_URL);

const novaRPC = new JsonRpcProvider(process.env.NOVA_URL);

await getCurrentRoles(arbOneRpc, "0x34d45e99f7D8c45ed05B5cA72D54bbD1fb3F98f0", "L2 Core Timelock");
await getCurrentRoles(arbOneRpc, "0xD509E5f5aEe2A205F554f36E8a7d56094494eDFC", "Security Council Manager");
await getCurrentRoles(arbOneRpc, "0xCF57572261c7c2BCF21ffD220ea7d1a27D40A827", "Arb1 Upgrade Executor");

await getCurrentRoles(ethRpc, "0xE6841D92B0C345144506576eC13ECf5103aC7f49", "L1 Timelock");
await getCurrentRoles(ethRpc, "0x3ffFbAdAF827559da092217e474760E2b2c3CeDd", "L1 Upgrade Executor");

await getCurrentRoles(novaRPC, "0x86a02dD71363c440b21F4c0E5B2Ad01Ffe1A7482", "Nova Upgrade Executor");
})();
Loading

0 comments on commit 06693a7

Please sign in to comment.