Skip to content

Commit

Permalink
feat: l1 robust deployment script
Browse files Browse the repository at this point in the history
  • Loading branch information
yiweichi committed Jul 25, 2024
1 parent ffa830b commit a87c7d7
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 92 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ broadcast

# Visual Studio Code
.vscode

volume
240 changes: 154 additions & 86 deletions scripts/deterministic/DeployScroll.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1011,148 +1011,216 @@ contract DeployScroll is DeterminsticDeployment {
**********************/

function initializeScrollChain() private {
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).initialize(
notnull(L1_MESSAGE_QUEUE_PROXY_ADDR),
notnull(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR),
MAX_TX_IN_CHUNK
);
if (getInitializeCount(L1_SCROLL_CHAIN_PROXY_ADDR) == 0) {
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).initialize(
notnull(L1_MESSAGE_QUEUE_PROXY_ADDR),
notnull(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR),
MAX_TX_IN_CHUNK
);
}

ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addSequencer(L1_COMMIT_SENDER_ADDR);
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addProver(L1_FINALIZE_SENDER_ADDR);
if (!ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).isSequencer(L1_COMMIT_SENDER_ADDR)) {
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addSequencer(L1_COMMIT_SENDER_ADDR);
}
if (!ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).isProver(L1_FINALIZE_SENDER_ADDR)) {
ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addProver(L1_FINALIZE_SENDER_ADDR);
}
}

function initializeL2GasPriceOracle() private {
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).initialize(
21000, // _txGas
53000, // _txGasContractCreation
4, // _zeroGas
16 // _nonZeroGas
);

L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).updateWhitelist(L1_WHITELIST_ADDR);
if (getInitializeCount(L2_GAS_PRICE_ORACLE_PROXY_ADDR) == 0) {
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).initialize(
21000, // _txGas
53000, // _txGasContractCreation
4, // _zeroGas
16 // _nonZeroGas
);
}
if (L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).whitelist() != L1_WHITELIST_ADDR) {
L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).updateWhitelist(L1_WHITELIST_ADDR);
}
}

function initializeL1MessageQueue() private {
L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initialize(
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR),
notnull(L1_SCROLL_CHAIN_PROXY_ADDR),
notnull(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR),
notnull(L2_GAS_PRICE_ORACLE_PROXY_ADDR),
MAX_L1_MESSAGE_GAS_LIMIT
);

L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initializeV2();
if (getInitializeCount(L1_MESSAGE_QUEUE_PROXY_ADDR) == 0) {
L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initialize(
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR),
notnull(L1_SCROLL_CHAIN_PROXY_ADDR),
notnull(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR),
notnull(L2_GAS_PRICE_ORACLE_PROXY_ADDR),
MAX_L1_MESSAGE_GAS_LIMIT
);
}
if (
getInitializeCount(L1_MESSAGE_QUEUE_PROXY_ADDR) == 0 || getInitializeCount(L1_MESSAGE_QUEUE_PROXY_ADDR) == 1
) {
L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initializeV2();
}
}

function initializeL1ScrollMessenger() private {
L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).initialize(
notnull(L2_SCROLL_MESSENGER_PROXY_ADDR),
notnull(L1_FEE_VAULT_ADDR),
notnull(L1_SCROLL_CHAIN_PROXY_ADDR),
notnull(L1_MESSAGE_QUEUE_PROXY_ADDR)
);
if (getInitializeCount(L1_SCROLL_MESSENGER_PROXY_ADDR) == 0) {
L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).initialize(
notnull(L2_SCROLL_MESSENGER_PROXY_ADDR),
notnull(L1_FEE_VAULT_ADDR),
notnull(L1_SCROLL_CHAIN_PROXY_ADDR),
notnull(L1_MESSAGE_QUEUE_PROXY_ADDR)
);
}
}

function initializeEnforcedTxGateway() private {
EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).initialize(
notnull(L1_MESSAGE_QUEUE_PROXY_ADDR),
notnull(L1_FEE_VAULT_ADDR)
);
if (getInitializeCount(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR) == 0) {
EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).initialize(
notnull(L1_MESSAGE_QUEUE_PROXY_ADDR),
notnull(L1_FEE_VAULT_ADDR)
);
}

// disable gateway
EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).setPause(true);
if (!EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).paused()) {
EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).setPause(true);
}
}

function initializeL1GatewayRouter() private {
L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).initialize(
notnull(L1_ETH_GATEWAY_PROXY_ADDR),
notnull(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR)
);
if (getInitializeCount(L1_GATEWAY_ROUTER_PROXY_ADDR) == 0) {
L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).initialize(
notnull(L1_ETH_GATEWAY_PROXY_ADDR),
notnull(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR)
);
}
}

function initializeL1CustomERC20Gateway() private {
L1CustomERC20Gateway(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR),
notnull(L1_GATEWAY_ROUTER_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
if (getInitializeCount(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR) == 0) {
L1CustomERC20Gateway(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR),
notnull(L1_GATEWAY_ROUTER_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
}
}

function initializeL1ERC1155Gateway() private {
L1ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_ERC1155_GATEWAY_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
if (getInitializeCount(L1_ERC1155_GATEWAY_PROXY_ADDR) == 0) {
L1ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_ERC1155_GATEWAY_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
}
}

function initializeL1ERC721Gateway() private {
L1ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_ERC721_GATEWAY_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
if (getInitializeCount(L1_ERC721_GATEWAY_PROXY_ADDR) == 0) {
L1ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_ERC721_GATEWAY_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
}
}

function initializeL1ETHGateway() private {
L1ETHGateway(L1_ETH_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_ETH_GATEWAY_PROXY_ADDR),
notnull(L1_GATEWAY_ROUTER_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
if (getInitializeCount(L1_ETH_GATEWAY_PROXY_ADDR) == 0) {
L1ETHGateway(L1_ETH_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_ETH_GATEWAY_PROXY_ADDR),
notnull(L1_GATEWAY_ROUTER_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
}
}

function initializeL1StandardERC20Gateway() private {
L1StandardERC20Gateway(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR),
notnull(L1_GATEWAY_ROUTER_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR),
notnull(L2_SCROLL_STANDARD_ERC20_ADDR),
notnull(L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR)
);
if (getInitializeCount(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR) == 0) {
L1StandardERC20Gateway(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize(
notnull(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR),
notnull(L1_GATEWAY_ROUTER_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR),
notnull(L2_SCROLL_STANDARD_ERC20_ADDR),
notnull(L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR)
);
}
}

function initializeL1WETHGateway() private {
L1WETHGateway(payable(L1_WETH_GATEWAY_PROXY_ADDR)).initialize(
notnull(L2_WETH_GATEWAY_PROXY_ADDR),
notnull(L1_GATEWAY_ROUTER_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
if (getInitializeCount(L1_WETH_GATEWAY_PROXY_ADDR) == 0) {
L1WETHGateway(payable(L1_WETH_GATEWAY_PROXY_ADDR)).initialize(
notnull(L2_WETH_GATEWAY_PROXY_ADDR),
notnull(L1_GATEWAY_ROUTER_PROXY_ADDR),
notnull(L1_SCROLL_MESSENGER_PROXY_ADDR)
);
}

// set WETH gateway in router
{
address[] memory _tokens = new address[](1);
_tokens[0] = notnull(L1_WETH_ADDR);
address[] memory _gateways = new address[](1);
_gateways[0] = notnull(L1_WETH_GATEWAY_PROXY_ADDR);
L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).setERC20Gateway(_tokens, _gateways);
if (L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).ERC20Gateway(_tokens[0]) != _gateways[0]) {
L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).setERC20Gateway(_tokens, _gateways);
}
}
}

function initializeL1Whitelist() private {
address[] memory accounts = new address[](1);
accounts[0] = L1_GAS_ORACLE_SENDER_ADDR;
Whitelist(L1_WHITELIST_ADDR).updateWhitelistStatus(accounts, true);
if (!Whitelist(L1_WHITELIST_ADDR).isSenderAllowed(accounts[0])) {
Whitelist(L1_WHITELIST_ADDR).updateWhitelistStatus(accounts, true);
}
}

function transferL1ContractOwnership() private {
if (DEPLOYER_ADDR == OWNER_ADDR) {
return;
}

Ownable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_ERC1155_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_ERC721_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_ETH_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_GATEWAY_ROUTER_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_MESSAGE_QUEUE_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_SCROLL_MESSENGER_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_WETH_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L2_GAS_PRICE_ORACLE_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_PROXY_ADMIN_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_SCROLL_CHAIN_PROXY_ADDR).transferOwnership(OWNER_ADDR);
Ownable(L1_WHITELIST_ADDR).transferOwnership(OWNER_ADDR);
if (Ownable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_ERC1155_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_ERC1155_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_ERC721_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_ERC721_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_ETH_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_ETH_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_GATEWAY_ROUTER_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_GATEWAY_ROUTER_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_MESSAGE_QUEUE_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_MESSAGE_QUEUE_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_SCROLL_MESSENGER_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_SCROLL_MESSENGER_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_WETH_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_WETH_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L2_GAS_PRICE_ORACLE_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L2_GAS_PRICE_ORACLE_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_PROXY_ADMIN_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_PROXY_ADMIN_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_SCROLL_CHAIN_PROXY_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_SCROLL_CHAIN_PROXY_ADDR).transferOwnership(OWNER_ADDR);
}
if (Ownable(L1_WHITELIST_ADDR).owner() != OWNER_ADDR) {
Ownable(L1_WHITELIST_ADDR).transferOwnership(OWNER_ADDR);
}
}

/**********************
Expand Down
25 changes: 19 additions & 6 deletions scripts/deterministic/DeterministicDeployment.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {stdToml} from "forge-std/StdToml.sol";

import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {ERC1967Upgrade} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol";

import {CONFIG_CONTRACTS_PATH, DEFAULT_DEPLOYMENT_SALT, DETERMINISTIC_DEPLOYMENT_PROXY_ADDR} from "./Constants.sol";
import {Configuration} from "./Configuration.sol";
Expand Down Expand Up @@ -115,19 +116,26 @@ abstract contract DeterminsticDeployment is Configuration {
address proxyAddr,
address implAddr
) internal {
if (!skipDeploy) {
address addr = _getImplementation(proxyAddr);

if (!skipDeploy && addr != implAddr) {
ProxyAdmin(notnull(proxyAdminAddr)).upgrade(
ITransparentUpgradeableProxy(notnull(proxyAddr)),
notnull(implAddr)
);
}
}

function getInitializeCount(address contractAddr) internal view returns (uint8) {
bytes32 slotValue = vm.load(address(contractAddr), bytes32(uint256(0)));
return uint8(uint256(slotValue));
}

/*********************
* Private functions *
*********************/

function _getSalt(string memory name) internal view returns (bytes32) {
function _getSalt(string memory name) private view returns (bytes32) {
return keccak256(abi.encodePacked(saltPrefix, name));
}

Expand All @@ -148,11 +156,9 @@ abstract contract DeterminsticDeployment is Configuration {
return addr;
}

// revert if the contract is already deployed
// skip if the contract is already deployed
if (addr.code.length > 0) {
revert(
string(abi.encodePacked("[ERROR] contract ", name, " (", vm.toString(addr), ") is already deployed"))
);
return addr;
}

// deploy contract
Expand Down Expand Up @@ -223,4 +229,11 @@ abstract contract DeterminsticDeployment is Configuration {
}
}
}

function _getImplementation(address proxyAddr) private view returns (address) {
// ERC1967Upgrade implementation slot
bytes32 _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
// get implementation address
return address(uint160(uint256(vm.load(address(proxyAddr), _IMPLEMENTATION_SLOT))));
}
}

0 comments on commit a87c7d7

Please sign in to comment.