-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Gary Ghayrat <[email protected]>
- Loading branch information
1 parent
f180c40
commit c89c349
Showing
16 changed files
with
2,308 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ARBITRUM_ONE_RPC_URL= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule forge-std
updated
41 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
// slither-disable-start reentrancy-benign | ||
|
||
pragma solidity 0.8.26; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
|
||
// Basic shared infrastructure for all deploy scripts | ||
contract BaseDeployer is Script { | ||
uint256 deployerPrivateKey; | ||
|
||
function setUp() public virtual { | ||
deployerPrivateKey = | ||
vm.envOr("DEPLOYER_PRIVATE_KEY", uint256(0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
// slither-disable-start reentrancy-benign | ||
|
||
pragma solidity 0.8.26; | ||
|
||
import {BaseDeployer} from "script/BaseDeployer.sol"; | ||
import {SharedGovernorConstants} from "script/SharedGovernorConstants.sol"; | ||
import {L2ArbitrumGovernorV2} from "src/L2ArbitrumGovernorV2.sol"; | ||
import {TransparentUpgradeableProxy} from | ||
"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; | ||
import {TimelockControllerUpgradeable} from | ||
"openzeppelin-upgradeable-v5/governance/TimelockControllerUpgradeable.sol"; | ||
import {IVotes} from "openzeppelin-v5/governance/utils/IVotes.sol"; | ||
|
||
// This base deployer contract is meant to be inherited by each concrete script written to deploy a specific governor, | ||
// namely the Treasury Governor and Core Governor. It includes the base deployment logic, shared constants, and | ||
// defines the virtual methods for values which must be provided by each concrete implementation. | ||
abstract contract BaseGovernorDeployer is BaseDeployer, SharedGovernorConstants { | ||
// Virtual methods returning initialization parameters that must be implemented by | ||
// each concrete deploy script. | ||
function NAME() public virtual returns (string memory); | ||
function TIMELOCK_ADDRESS() public virtual returns (address payable); | ||
function QUORUM_NUMERATOR() public virtual returns (uint256); | ||
|
||
function run(address _implementation) public virtual returns (L2ArbitrumGovernorV2 _governor) { | ||
vm.startBroadcast(deployerPrivateKey); | ||
bytes memory _initData = abi.encodeCall( | ||
L2ArbitrumGovernorV2.initialize, | ||
( | ||
NAME(), | ||
INITIAL_VOTING_DELAY, | ||
INITIAL_VOTING_PERIOD, | ||
INITIAL_PROPOSAL_THRESHOLD, | ||
IVotes(L2_ARB_TOKEN_ADDRESS), | ||
TimelockControllerUpgradeable(TIMELOCK_ADDRESS()), | ||
QUORUM_NUMERATOR(), | ||
INITIAL_VOTE_EXTENSION, | ||
L2_UPGRADE_EXECUTOR | ||
) | ||
); | ||
TransparentUpgradeableProxy _proxy = | ||
new TransparentUpgradeableProxy(_implementation, L2_PROXY_ADMIN, _initData); | ||
_governor = L2ArbitrumGovernorV2(payable(address(_proxy))); | ||
vm.stopBroadcast(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
// slither-disable-start reentrancy-benign | ||
|
||
pragma solidity 0.8.26; | ||
|
||
import {BaseGovernorDeployer, L2ArbitrumGovernorV2} from "script/BaseGovernorDeployer.sol"; | ||
|
||
// Concrete deployment script for the Arbitrum L2 Core Governor. | ||
contract DeployCoreGovernor is BaseGovernorDeployer { | ||
function NAME() public pure override returns (string memory) { | ||
return "Core L2ArbitrumGovernor"; | ||
} | ||
|
||
function TIMELOCK_ADDRESS() public pure override returns (address payable) { | ||
return payable(L2_CORE_GOVERNOR_TIMELOCK); | ||
} | ||
|
||
function QUORUM_NUMERATOR() public pure override returns (uint256) { | ||
return 500; | ||
} | ||
|
||
function run(address _implementation) public override returns (L2ArbitrumGovernorV2 _governor) { | ||
return super.run(_implementation); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
// slither-disable-start reentrancy-benign | ||
|
||
pragma solidity 0.8.26; | ||
|
||
import {BaseDeployer} from "script/BaseDeployer.sol"; | ||
import {L2ArbitrumGovernorV2} from "src/L2ArbitrumGovernorV2.sol"; | ||
|
||
// Deploy script for the underlying implementation that will be used by both Governor proxies | ||
contract DeployImplementation is BaseDeployer { | ||
function run() public returns (L2ArbitrumGovernorV2 _implementation) { | ||
vm.startBroadcast(deployerPrivateKey); | ||
_implementation = new L2ArbitrumGovernorV2(); | ||
vm.stopBroadcast(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
// slither-disable-start reentrancy-benign | ||
|
||
pragma solidity 0.8.26; | ||
|
||
import {BaseDeployer} from "script/BaseDeployer.sol"; | ||
import {TimelockRolesUpgrader} from | ||
"src/gov-action-contracts/gov-upgrade-contracts/update-timelock-roles/TimelockRolesUpgrader.sol"; | ||
import {SharedGovernorConstants} from "script/SharedGovernorConstants.sol"; | ||
|
||
contract DeployTimelockRolesUpgrader is BaseDeployer, SharedGovernorConstants { | ||
function run(address _newCoreGovernor, address _newTreasuryGovernor) | ||
public | ||
returns (TimelockRolesUpgrader timelockRolesUpgrader) | ||
{ | ||
vm.startBroadcast(); | ||
timelockRolesUpgrader = new TimelockRolesUpgrader( | ||
L2_CORE_GOVERNOR_TIMELOCK, | ||
L2_CORE_GOVERNOR, | ||
_newCoreGovernor, | ||
L2_TREASURY_GOVERNOR_TIMELOCK, | ||
L2_TREASURY_GOVERNOR, | ||
_newTreasuryGovernor | ||
); | ||
vm.stopBroadcast(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
// slither-disable-start reentrancy-benign | ||
|
||
pragma solidity 0.8.26; | ||
|
||
import {BaseGovernorDeployer, L2ArbitrumGovernorV2} from "script/BaseGovernorDeployer.sol"; | ||
|
||
// Concrete deployment script for the Arbitrum L2 Core Governor. | ||
contract DeployTreasuryGovernor is BaseGovernorDeployer { | ||
function NAME() public pure override returns (string memory) { | ||
return "Treasury L2ArbitrumGovernor"; | ||
} | ||
|
||
function TIMELOCK_ADDRESS() public pure override returns (address payable) { | ||
return payable(L2_TREASURY_GOVERNOR_TIMELOCK); | ||
} | ||
|
||
function QUORUM_NUMERATOR() public pure override returns (uint256) { | ||
return 300; | ||
} | ||
|
||
function run(address _implementation) public override returns (L2ArbitrumGovernorV2 _governor) { | ||
return super.run(_implementation); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
// slither-disable-start reentrancy-benign | ||
|
||
pragma solidity 0.8.26; | ||
|
||
// Inheritable extension holding governor deployment constants that are shared between the Core Governor and the | ||
// Treasury Governor. These should be carefully checked and reviewed before final deployment. | ||
contract SharedGovernorConstants { | ||
uint256 constant FORK_BLOCK = 245_608_716; // Arbitrary recent block | ||
address public constant L2_ARB_TOKEN_ADDRESS = 0x912CE59144191C1204E64559FE8253a0e49E6548; | ||
|
||
address public constant L2_CORE_GOVERNOR = 0xf07DeD9dC292157749B6Fd268E37DF6EA38395B9; | ||
address public constant L2_CORE_GOVERNOR_TIMELOCK = 0x34d45e99f7D8c45ed05B5cA72D54bbD1fb3F98f0; | ||
address public constant L2_TREASURY_GOVERNOR = 0x789fC99093B09aD01C34DC7251D0C89ce743e5a4; | ||
address public constant L2_TREASURY_GOVERNOR_TIMELOCK = | ||
0xbFc1FECa8B09A5c5D3EFfE7429eBE24b9c09EF58; | ||
address public constant L2_PROXY_ADMIN = 0xdb216562328215E010F819B5aBe947bad4ca961e; | ||
|
||
address public constant L2_ARB_SYS = 0x0000000000000000000000000000000000000064; | ||
address public constant L2_ARB_TREASURY_FIXED_DELEGATE = | ||
0xF3FC178157fb3c87548bAA86F9d24BA38E649B58; | ||
address public constant L2_ARB_RETRYABLE_TX = 0x000000000000000000000000000000000000006E; | ||
address public constant L2_SECURITY_COUNCIL_9 = 0x423552c0F05baCCac5Bfa91C6dCF1dc53a0A1641; | ||
|
||
address public constant L1_TIMELOCK = 0xE6841D92B0C345144506576eC13ECf5103aC7f49; | ||
uint256 public constant L1_TIMELOCK_MIN_DELAY = 259_200; // TODO: Make sure this is up to date. | ||
address public constant L1_ARB_ONE_DELAYED_INBOX = 0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f; | ||
|
||
address public constant L2_CORE_GOVERNOR_ONCHAIN = 0x7796F378B3c56ceD57350B938561D8c52256456b; | ||
address public constant L2_TREASURY_GOVERNOR_ONCHAIN = | ||
0x4fd1216c8b5E72b22785169Ae5C1e8f3b30C19E4; | ||
bool public constant UPGRADE_PROPOSAL_PASSED_ONCHAIN = false; // TODO: Update after the upgrade proposal is passed. | ||
|
||
address public constant L2_UPGRADE_EXECUTOR = 0xCF57572261c7c2BCF21ffD220ea7d1a27D40A827; | ||
|
||
address public constant RETRYABLE_TICKET_MAGIC = 0xa723C008e76E379c55599D2E4d93879BeaFDa79C; | ||
|
||
address public constant EXCLUDE_ADDRESS = address(0xA4b86); | ||
uint256 public constant QUORUM_DENOMINATOR = 10_000; | ||
|
||
bytes32 public constant TIMELOCK_PROPOSER_ROLE = | ||
0xb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1; | ||
|
||
uint8 public constant VOTE_TYPE_FRACTIONAL = 255; | ||
|
||
// These values match the current production values for both governors. Note that they are expressed in L1 blocks, | ||
// with an assumed 12 second block time, because on Arbitrum, block.number returns the number of the L1. | ||
uint48 public constant INITIAL_VOTING_DELAY = 21_600; // 3 days | ||
uint32 public constant INITIAL_VOTING_PERIOD = 100_800; // 14 days | ||
uint48 public constant INITIAL_VOTE_EXTENSION = 14_400; // 2 days | ||
|
||
// This value matches the current production value for both governors. 1M Arb in raw decimals. | ||
uint256 public constant INITIAL_PROPOSAL_THRESHOLD = 1_000_000_000_000_000_000_000_000; | ||
|
||
address[] public _majorDelegates; | ||
|
||
enum ProposalState { | ||
Pending, | ||
Active, | ||
Canceled, | ||
Defeated, | ||
Succeeded, | ||
Queued, | ||
Expired, | ||
Executed | ||
} | ||
|
||
enum VoteType { | ||
Against, | ||
For, | ||
Abstain | ||
} | ||
|
||
constructor() { | ||
_majorDelegates = new address[](18); | ||
_majorDelegates[0] = 0x1B686eE8E31c5959D9F5BBd8122a58682788eeaD; // L2BEAT | ||
_majorDelegates[1] = 0xF4B0556B9B6F53E00A1FDD2b0478Ce841991D8fA; // olimpio | ||
_majorDelegates[2] = 0x11cd09a0c5B1dc674615783b0772a9bFD53e3A8F; // Gauntlet | ||
_majorDelegates[3] = 0xB933AEe47C438f22DE0747D57fc239FE37878Dd1; // Wintermute | ||
_majorDelegates[4] = 0x0eB5B03c0303f2F47cD81d7BE4275AF8Ed347576; // Treasure | ||
_majorDelegates[5] = 0xF92F185AbD9E00F56cb11B0b709029633d1E37B4; // | ||
_majorDelegates[6] = 0x186e505097BFA1f3cF45c2C9D7a79dE6632C3cdc; | ||
_majorDelegates[7] = 0x5663D01D8109DDFC8aACf09fBE51F2d341bb3643; | ||
_majorDelegates[8] = 0x2ef27b114917dD53f8633440A7C0328fef132e2F; // MUX Protocol | ||
_majorDelegates[9] = 0xE48C655276C23F1534AE2a87A2bf8A8A6585Df70; // ercwl | ||
_majorDelegates[10] = 0x8A3e9846df0CDc723C06e4f0C642ffFF82b54610; | ||
_majorDelegates[11] = 0xAD16ebE6FfC7d96624A380F394cD64395B0C6144; // DK (Premia) | ||
_majorDelegates[12] = 0xA5dF0cf3F95C6cd97d998b9D990a86864095d9b0; // Blockworks Research | ||
_majorDelegates[13] = 0x839395e20bbB182fa440d08F850E6c7A8f6F0780; // Griff Green | ||
_majorDelegates[14] = 0x2e3BEf6830Ae84bb4225D318F9f61B6b88C147bF; // Camelot | ||
_majorDelegates[15] = 0x8F73bE66CA8c79382f72139be03746343Bf5Faa0; // mihal.eth | ||
_majorDelegates[16] = 0xb5B069370Ef24BC67F114e185D185063CE3479f8; // Frisson | ||
_majorDelegates[17] = 0xdb5781a835b60110298fF7205D8ef9678Ff1f800; // yoav.eth | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
// slither-disable-start reentrancy-benign | ||
|
||
pragma solidity 0.8.26; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
import {SharedGovernorConstants} from "script/SharedGovernorConstants.sol"; | ||
import {GovernorUpgradeable} from "openzeppelin-upgradeable-v5/governance/GovernorUpgradeable.sol"; | ||
import {CreateL2ArbSysProposal} from "script/helpers/CreateL2ArbSysProposal.sol"; | ||
|
||
contract SubmitUpgradeProposalScript is Script, SharedGovernorConstants, CreateL2ArbSysProposal { | ||
// TODO: Update `PROPOSER` to script msg.sender who will submit the proposal. | ||
address PROPOSER = 0x1B686eE8E31c5959D9F5BBd8122a58682788eeaD; // L2Beat | ||
// TODO: Update `minDelay` to latest getMinDelay() from L1Timelock. | ||
uint256 minDelay = 259_200; | ||
|
||
function run(address _timelockRolesUpgrader) | ||
public | ||
returns ( | ||
address[] memory targets, | ||
uint256[] memory values, | ||
bytes[] memory calldatas, | ||
string memory description, | ||
uint256 _proposalId | ||
) | ||
{ | ||
return proposeUpgrade(_timelockRolesUpgrader); | ||
} | ||
|
||
function proposeUpgrade(address _timelockRolesUpgrader) | ||
internal | ||
returns ( | ||
address[] memory _targets, | ||
uint256[] memory _values, | ||
bytes[] memory _calldatas, | ||
string memory _description, | ||
uint256 _proposalId | ||
) | ||
{ | ||
// TODO: Before deployment update `_description` with the new governor contract addresses. | ||
_description = | ||
"# Proposal to Upgrade Governor Contracts \ | ||
\ | ||
### **Abstract** \ | ||
This proposal will transfer the proposer and canceller roles from the current Arbitrum Core Governor and Arbitrum Treasury Governor to newly deployed Governor contracts. This roles transfer is a crucial step in upgrading the Arbitrum DAO's governance infrastructure. \ | ||
\ | ||
### Motivation \ | ||
This upgrade to the Arbitrum DAO's governance system was initially discussed as part of the 'Expand Tally Support for the Arbitrum DAO' proposal https://forum.arbitrum.foundation/t/expand-tally-support-for-the-arbitrum-dao/22387. The community recognized the need for enhanced governance features, including proposal cancellation and flexible voting mechanisms. \ | ||
\ | ||
As a result of these discussions, new Governor contracts have been developed and deployed with these improvements. To activate these enhancements and complete the upgrade process, we now need to transfer the proposer role to these new contracts. \ | ||
\ | ||
### **Specifications** \ | ||
This proposal will: \ | ||
\ | ||
1. Grant the newly deployed Core Governor and Treasury Governor contracts the 'PROPOSER_ROLE' and 'CANCELLER_ROLE' on the timelock contract. \ | ||
2. Revoke the current Core Governor and Treasury Governor contracts' 'PROPOSER_ROLE' and 'CANCELLER_ROLE' on the timelock contract. \ | ||
\ | ||
### **Technical Details** \ | ||
- The new Governor contracts have been deployed on Arbitrum One at the following addresses: \ | ||
TODO: [Insert new Core Governor address] \ | ||
TODO: [Insert new Treasury Governor address] \ | ||
\ | ||
- These new contracts include the following enhancements: \ | ||
1. Proposal Cancellation: Allows the delegate who submitted a proposal to cancel it during the delay phase, before voting begins. \ | ||
2. Flexible Voting: Enables delegates to cast rolling, fractional votes, supporting future innovations like voting from Orbit chains and more. \ | ||
\ | ||
- The new Governors maintain all existing features of the current Governors, including custom relay functionality and fractional quorum calculations. \ | ||
\ | ||
### **Rationale** \ | ||
The rationale for upgrading the Governors by granting and revoking roles on the Timelock contract instead of using the proxy upgradeable contract pattern is discussed in this forum post: https://forum.arbitrum.foundation/t/arbitrum-governance-smart-contract-upgrade-technical-details/24642 \ | ||
\ | ||
### **Security Considerations** \ | ||
- The new Governor contracts have been tested and audited by OpenZeppelin. \ | ||
- This transfer does not move any funds or change permissions on the Timelock contracts. \ | ||
- Historical governance actions will remain visible and valid. \ | ||
\ | ||
### **Post-Transfer Actions** \ | ||
- Immediately after this transfer executes, Tally will update to interface with the new Governor contracts. \ | ||
- Delegates should use the new Governor contracts for all future proposal submissions. \ | ||
- The old Governor contracts will remain on-chain but will no longer have the ability to execute proposals. \ | ||
\ | ||
### **Timeline** \ | ||
If this proposal passes, the transfer will be executed immediately after the Timelock delay. \ | ||
\ | ||
By approving this proposal, the Arbitrum DAO will upgrade its governance infrastructure, enabling new features and improvements in the governance process. \ | ||
"; | ||
(_targets, _values, _calldatas) = | ||
createL2ArbSysProposal(_description, _timelockRolesUpgrader, minDelay); | ||
vm.startBroadcast(PROPOSER); | ||
_proposalId = GovernorUpgradeable(payable(L2_CORE_GOVERNOR)).propose( | ||
_targets, _values, _calldatas, _description | ||
); | ||
vm.stopBroadcast(); | ||
} | ||
} |
Oops, something went wrong.