Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Orbit governance deployment scripts #219

Merged
merged 15 commits into from
Nov 14, 2024
Merged
8 changes: 4 additions & 4 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ L2SecurityCouncilMgmtFactoryTest:testRemovalGovDeployment() (gas: 30526232)
L2SecurityCouncilMgmtFactoryTest:testSecurityCouncilManagerDeployment() (gas: 30545325)
NomineeGovernorV2UpgradeActionTest:testAction() (gas: 8153)
OfficeHoursActionTest:testConstructor() (gas: 9050)
OfficeHoursActionTest:testFuzzOfficeHoursDeployment(uint256,uint256,int256,uint256,uint256,uint256) (runs: 258, μ: 317071, ~: 317184)
OfficeHoursActionTest:testFuzzOfficeHoursDeployment(uint256,uint256,int256,uint256,uint256,uint256) (runs: 256, μ: 317064, ~: 317184)
OfficeHoursActionTest:testInvalidConstructorParameters() (gas: 235740)
OfficeHoursActionTest:testPerformBeforeMinimumTimestamp() (gas: 8646)
OfficeHoursActionTest:testPerformDuringOfficeHours() (gas: 9140)
Expand Down Expand Up @@ -153,7 +153,7 @@ SecurityCouncilMemberElectionGovernorTest:testOnlyNomineeElectionGovernorCanProp
SecurityCouncilMemberElectionGovernorTest:testProperInitialization() (gas: 49388)
SecurityCouncilMemberElectionGovernorTest:testProposeReverts() (gas: 32916)
SecurityCouncilMemberElectionGovernorTest:testRelay() (gas: 42229)
SecurityCouncilMemberElectionGovernorTest:testSelectTopNominees(uint256) (runs: 258, μ: 339983, ~: 339822)
SecurityCouncilMemberElectionGovernorTest:testSelectTopNominees(uint256) (runs: 256, μ: 340112, ~: 339983)
SecurityCouncilMemberElectionGovernorTest:testSelectTopNomineesFails() (gas: 273335)
SecurityCouncilMemberElectionGovernorTest:testSetFullWeightDuration() (gas: 34951)
SecurityCouncilMemberElectionGovernorTest:testVotesToWeight() (gas: 152898)
Expand Down Expand Up @@ -202,11 +202,11 @@ SecurityCouncilNomineeElectionGovernorTest:testProperInitialization() (gas: 7811
SecurityCouncilNomineeElectionGovernorTest:testProposeFails() (gas: 19740)
SecurityCouncilNomineeElectionGovernorTest:testRelay() (gas: 42427)
SecurityCouncilNomineeElectionGovernorTest:testSetNomineeVetter() (gas: 39905)
SequencerActionsTest:testAddAndRemoveSequencer() (gas: 483532)
SequencerActionsTest:testAddAndRemoveSequencer() (gas: 483628)
SequencerActionsTest:testCantAddZeroAddress() (gas: 235614)
SetInitialGovParamsActionTest:testL1() (gas: 259904)
SetInitialGovParamsActionTest:testL2() (gas: 688888)
SetSequencerInboxMaxTimeVariationAction:testSetMaxTimeVariation() (gas: 374262)
SetSequencerInboxMaxTimeVariationAction:testSetMaxTimeVariation() (gas: 308231)
SwitchManagerRolesActionTest:testAction() (gas: 6313)
TokenDistributorTest:testClaim() (gas: 5742744)
TokenDistributorTest:testClaimAndDelegate() (gas: 5850827)
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"deploy:note-store": "ts-node ./scripts/deployNoteStore.ts",
"deploy:vested-wallets": "ts-node ./scripts/vestedWalletsDeployer.ts",
"deploy:dummy-elections": "yarn build:sc-mgmt && ts-node scripts/security-council-mgmt-deployment/deployDummyElectionsContracts.ts",
"deploy:orbit:governance": "ts-node ./scripts/orbit-chain-governance/orbitGovernanceDeployer.ts",
"gen:proposalData": "ts-node ./scripts/propBuilderCli.ts",
"verify:vested-wallets": "ts-node ./scripts/vestedWalletsDeploymentVerifier.ts",
"verify:governance": "ts-node ./scripts/governanceDeploymentVerifier.ts",
Expand Down Expand Up @@ -76,8 +77,8 @@
"typescript": "^4.8.4"
},
"dependencies": {
"@arbitrum/nitro-contracts": "1.1.1",
"@arbitrum/token-bridge-contracts": "1.0.0-beta.0",
"@arbitrum/nitro-contracts": "^2.1.0",
"@arbitrum/token-bridge-contracts": "^1.2.3",
"@gnosis.pm/safe-contracts": "1.3.0",
"@openzeppelin/contracts": "4.7.3",
"@openzeppelin/contracts-upgradeable": "4.7.3",
Expand Down
280 changes: 280 additions & 0 deletions scripts/orbit-chain-governance/orbitGovernanceDeployer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
import { Wallet, ethers } from "ethers";
import {
GovernanceChainGovFactory__factory,
IBridge__factory,
IInbox__factory,
ParentChainGovFactory__factory,
WrappedNativeGovToken__factory,
} from "../../typechain-types";
import { Filter, JsonRpcProvider, Provider } from "@ethersproject/providers";
import { execSync } from "child_process";
import dotenv from "dotenv";
import { Interface } from "@ethersproject/abi";
import { RollupCore__factory } from "@arbitrum/sdk/dist/lib/abi/factories/RollupCore__factory";
import { IOwnable__factory } from "../../token-bridge-contracts/build/types";

dotenv.config();

export const deployGovernance = async () => {
// load env vars
const parentChainRpc = process.env["PARENT_CHAIN_RPC"] as string;
const parentChainDeployKey = process.env["PARENT_CHAIN_DEPLOY_KEY"] as string;
const childChainRpc = process.env["CHILD_CHAIN_RPC"] as string;
const childChainDeployKey = process.env["CHILD_CHAIN_DEPLOY_KEY"] as string;
const inboxAddress = process.env["INBOX_ADDRESS"] as string;
const tokenBridgeCreatorAddress = process.env["TOKEN_BRIDGE_CREATOR_ADDRESS"] as string;
if (
![
parentChainRpc,
parentChainDeployKey,
childChainRpc,
childChainDeployKey,
inboxAddress,
tokenBridgeCreatorAddress,
].every(Boolean)
) {
throw new Error(
"Following env vars have to be set: PARENT_CHAIN_RPC, PARENT_CHAIN_DEPLOY_KEY, CHILD_CHAIN_RPC, CHILD_CHAIN_DEPLOY_KEY, INBOX_ADDRESS, TOKEN_BRIDGE_CREATOR_ADDRESS"
);
}

// deploy parent chain governance factory
const parentChainDeployerWallet = new Wallet(parentChainDeployKey).connect(
new JsonRpcProvider(parentChainRpc)
);
const parentChainFactoryFac = await new ParentChainGovFactory__factory(
parentChainDeployerWallet
).deploy();
const parentChainFactory = await parentChainFactoryFac.deployed();
console.log("ParentChainGovFactory: ", parentChainFactory.address);

// deploy child chain governance factory
const childChainDeployerWallet = new Wallet(childChainDeployKey).connect(
new JsonRpcProvider(childChainRpc)
);
const childChainFactoryFac = await new GovernanceChainGovFactory__factory(
childChainDeployerWallet
).deploy();
const childChainFactory = await childChainFactoryFac.deployed();
console.log("GovernanceChainGov: ", childChainFactory.address);

// deploy governance token
const governanceTokenFac = await new WrappedNativeGovToken__factory(
childChainDeployerWallet
).deploy();
const governanceToken = await governanceTokenFac.deployed();
console.log("GovernanceToken: ", governanceToken.address);

// get deployment data
const { childChainUpExec, childChainProxyAdmin, parentChainUpExec, parentChainProxyAdmin } =
await getDeploymentData(
parentChainDeployerWallet.provider!,
inboxAddress,
tokenBridgeCreatorAddress
);

/// step1
const deploymentReceipt = await (
await childChainFactory.deployStep1({
_governanceToken: governanceToken.address,
_govChainUpExec: childChainUpExec,
_govChainProxyAdmin: childChainProxyAdmin,
_proposalThreshold: 100,
_votingPeriod: 10,
_votingDelay: 10,
_minTimelockDelay: 7,
_minPeriodAfterQuorum: 1,
_coreQuorumThreshold: 500,
})
).wait();
console.log("Step1 finished");

//// step 2
const { coreTimelock: _childChainCoreTimelock, coreGoverner: _childChainCoreGov } =
_getParsedLogs(deploymentReceipt.logs, childChainFactory.interface, "Deployed")[0].args;
const _minTimelockDelay = 7;

await (
await parentChainFactory.deployStep2(
parentChainUpExec,
parentChainProxyAdmin,
inboxAddress,
_childChainCoreTimelock,
_minTimelockDelay
)
).wait();
console.log("Step2 finished");
};

async function getDeploymentData(
parentChainProvider: Provider,
inboxAddress: string,
tokenBridgeCreatorAddress: string
) {
/// get child chain deployment data
const tokenBridgeCreator = new ethers.Contract(
tokenBridgeCreatorAddress,
tokenBridgeCreatorABI,
parentChainProvider
);
const [, , , , , childChainProxyAdmin, , childChainUpExec, ,] =
await tokenBridgeCreator.inboxToL2Deployment(inboxAddress);

/// get parent chain info
const bridge = await IInbox__factory.connect(inboxAddress, parentChainProvider).bridge();
const rollup = await IBridge__factory.connect(bridge, parentChainProvider).rollup();
const parentChainUpExec = await IOwnable__factory.connect(rollup, parentChainProvider).owner();
const iinboxProxyAdmin = new ethers.Contract(
inboxAddress,
iinboxProxyAdminABI,
parentChainProvider
);
const parentChainProxyAdmin = await iinboxProxyAdmin.getProxyAdmin();

let data = {
childChainUpExec,
childChainProxyAdmin,
parentChainUpExec,
parentChainProxyAdmin,
};

return data;
}

export const _getParsedLogs = (
logs: ethers.providers.Log[],
iface: ethers.utils.Interface,
eventName: string
) => {
const eventFragment = iface.getEvent(eventName);
const parsedLogs = logs
.filter((curr: any) => curr.topics[0] === iface.getEventTopic(eventFragment))
.map((curr: any) => iface.parseLog(curr));
return parsedLogs;
};

//// subset of token bridge creator ABI
const tokenBridgeCreatorABI = [
{
inputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
name: "inboxToL1Deployment",
outputs: [
{
internalType: "address",
name: "router",
type: "address",
},
{
internalType: "address",
name: "standardGateway",
type: "address",
},
{
internalType: "address",
name: "customGateway",
type: "address",
},
{
internalType: "address",
name: "wethGateway",
type: "address",
},
{
internalType: "address",
name: "weth",
type: "address",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
name: "inboxToL2Deployment",
outputs: [
{
internalType: "address",
name: "router",
type: "address",
},
{
internalType: "address",
name: "standardGateway",
type: "address",
},
{
internalType: "address",
name: "customGateway",
type: "address",
},
{
internalType: "address",
name: "wethGateway",
type: "address",
},
{
internalType: "address",
name: "weth",
type: "address",
},
{
internalType: "address",
name: "proxyAdmin",
type: "address",
},
{
internalType: "address",
name: "beaconProxyFactory",
type: "address",
},
{
internalType: "address",
name: "upgradeExecutor",
type: "address",
},
{
internalType: "address",
name: "multicall",
type: "address",
},
],
stateMutability: "view",
type: "function",
},
];

const iinboxProxyAdminABI = [
{
inputs: [],
name: "getProxyAdmin",
outputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
stateMutability: "view",
type: "function",
},
];

async function main() {
console.log("Start governance deployment process...");
await deployGovernance();
console.log("Deployment finished!");
}

main().then(() => console.log("Done."));
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ contract ParentChainGovFactory is Ownable {
// anyone can execute
timelock.grantRole(timelock.EXECUTOR_ROLE(), address(0));

// revoke admin rights and give them to the upgrade executor
// grant timelock admin rights to the upgrade executor
timelock.grantRole(timelock.TIMELOCK_ADMIN_ROLE(), address(_parentChainUpExec));
timelock.revokeRole(timelock.TIMELOCK_ADMIN_ROLE(), address(timelock));
timelock.revokeRole(timelock.TIMELOCK_ADMIN_ROLE(), address(this));

// grant canceller role to upgrade executor; this can be used e.g. by an admin with executor affordance granted to the upgrade executor
timelock.grantRole(timelock.CANCELLER_ROLE(), address(_parentChainUpExec));

// revoke admin rights
timelock.revokeRole(timelock.TIMELOCK_ADMIN_ROLE(), address(timelock));
timelock.revokeRole(timelock.TIMELOCK_ADMIN_ROLE(), address(this));

emit Deployed(timelock, _inbox);
}

Expand Down
4 changes: 2 additions & 2 deletions test/util/ActionTestBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ abstract contract ActionTestBase {
rollup.transferOwnership(address(ue));
bridge = Bridge(TestUtil.deployProxy(address(new Bridge())));
bridge.initialize(IOwnable(address(rollup)));
si = SequencerInbox(TestUtil.deployProxy(address(new SequencerInbox(117964))));
si = SequencerInbox(TestUtil.deployProxy(address(new SequencerInbox(117964, IReader4844(address(200)), false))));
si.initialize(bridge, ISequencerInbox.MaxTimeVariation(0, 0, 0, 0));
inbox = Inbox(TestUtil.deployProxy(address(new Inbox(117964))));
inbox.initialize(bridge, si);
inbox.initialize(bridge, si);

l1Timelock =
L1ArbitrumTimelock(payable(TestUtil.deployProxy(address(new L1ArbitrumTimelock()))));
Expand Down
2 changes: 1 addition & 1 deletion token-bridge-contracts
Submodule token-bridge-contracts updated 34 files
+1 −0 .circleci/config.yml
+3 −3 _deployments/1_42170_current_deployment.json
+3 −3 _deployments/1_current_deployment.json
+3 −3 _deployments/42161_current_deployment.json
+3 −3 _deployments/42170_current_deployment.json
+0 −40 contracts/tokenbridge/arbitrum/ReverseArbToken.sol
+1 −0 contracts/tokenbridge/arbitrum/gateway/L2GatewayRouter.sol
+0 −63 contracts/tokenbridge/arbitrum/gateway/L2ReverseCustomGateway.sol
+2 −0 contracts/tokenbridge/arbitrum/gateway/L2WethGateway.sol
+0 −4 contracts/tokenbridge/ethereum/ICustomToken.sol
+1 −1 contracts/tokenbridge/ethereum/gateway/L1ArbitrumExtendedGateway.sol
+1 −0 contracts/tokenbridge/ethereum/gateway/L1ArbitrumGateway.sol
+1 −1 contracts/tokenbridge/ethereum/gateway/L1CustomGateway.sol
+168 −1 contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol
+0 −57 contracts/tokenbridge/ethereum/gateway/L1ReverseCustomGateway.sol
+14 −2 contracts/tokenbridge/ethereum/gateway/L1WethGateway.sol
+24 −0 contracts/tokenbridge/libraries/IDaiLikePermit.sol
+0 −45 contracts/tokenbridge/libraries/L2CustomGatewayToken.sol
+76 −0 contracts/tokenbridge/libraries/gateway/GatewayRouter.sol
+56 −0 contracts/tokenbridge/libraries/gateway/IGatewayRouter.sol
+2 −25 contracts/tokenbridge/test/TestArbCustomToken.sol
+12 −54 contracts/tokenbridge/test/TestCustomTokenL1.sol
+10 −13 contracts/tokenbridge/test/TestERC20Permit.sol
+128 −0 contracts/tokenbridge/test/TestERC20PermitDai.sol
+289 −0 contracts/tokenbridge/test/TestERC20PermitNoVersion.sol
+3 −3 hardhat.config.ts
+90 −23 test/canonicalBridge.l1.ts
+5 −0 test/canonicalBridge.l2.ts
+344 −0 test/gatewayRouter.l1.ts
+0 −426 test/reverseCustomGateway.e2e.ts
+146 −1 test/testhelper.ts
+87 −49 test/wethBridge.l1.ts
+5 −0 test/wethBridge.l2.ts
+821 −829 yarn.lock
Loading
Loading