Skip to content

feat: deploy Rollup contracts #76

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

Merged
merged 7 commits into from
Sep 23, 2024
Merged
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
9 changes: 9 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@
[submodule "lib/permit2"]
path = lib/permit2
url = https://github.com/Uniswap/permit2
[submodule "lib/simple-erc20"]
path = lib/simple-erc20
url = https://github.com/init4tech/simple-erc20
[submodule "lib/safe-smart-account"]
path = lib/safe-smart-account
url = https://github.com/safe-global/safe-smart-account
[submodule "lib/stablecoin-evm"]
path = lib/stablecoin-evm
url = https://github.com/circlefin/stablecoin-evm
1 change: 1 addition & 0 deletions lib/safe-smart-account
Submodule safe-smart-account added at bf943f
1 change: 1 addition & 0 deletions lib/simple-erc20
Submodule simple-erc20 added at 36523a
1 change: 1 addition & 0 deletions lib/stablecoin-evm
Submodule stablecoin-evm added at 405efc
99 changes: 99 additions & 0 deletions script/DeployGnosisSafe.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity 0.8.26;

// deps
import {SafeL2} from "safe-smart-account/contracts/SafeL2.sol";
import {SafeProxyFactory} from "safe-smart-account/contracts/proxies/SafeProxyFactory.sol";
import {CompatibilityFallbackHandler} from "safe-smart-account/contracts/handler/CompatibilityFallbackHandler.sol";
// script deps
import {Script, console2} from "forge-std/Script.sol";

struct SafeSetup {
address[] owners;
uint256 threshold;
address to;
bytes data;
address fallbackHandler;
address paymentToken;
uint256 payment;
address payable paymentReceiver;
uint256 saltNonce;
}

address constant OWNER_ONE = 0x1111111111111111111111111111111111111111;
address constant OWNER_TWO = 0x2222222222222222222222222222222222222222;
bytes32 constant SENTINEL_VALUE = 0x0000000000000000000000000000000000000000000000000000000000000001;

contract GnosisScript is Script {
// deploy:
// forge script GnosisScript --sig "deployGnosis()" --rpc-url $RPC_URL --broadcast [signing args]
function deployGnosis()
public
returns (address gnosisFactory, address gnosisSingleton, address gnosisFallbackHandler, address usdcAdmin)
{
vm.startBroadcast();

// deploy gnosis safe singleton & proxy factory
(gnosisFactory, gnosisSingleton, gnosisFallbackHandler) = deployGnosisCore();

// deploy a gnosis safe proxy as the USDC admin
usdcAdmin = deploySafeInstance(gnosisFactory, gnosisSingleton, getUsdcAdminSetup(gnosisFallbackHandler));
}

function deployGnosisCore() public returns (address factory, address singleton, address fallbackHandler) {
factory = address(new SafeProxyFactory{salt: "zenith.gnosisFactory"}());
singleton = address(new SafeL2{salt: "zenith.gnosisSingleton"}());
fallbackHandler = address(new CompatibilityFallbackHandler{salt: "zenith.gnosisFallbackHandlder"}());
}

function deploySafeInstance(address factory, address singleton, SafeSetup memory setup)
public
returns (address safe)
{
bytes memory init = abi.encodeWithSignature(
"setup(address[],uint256,address,bytes,address,address,uint256,address)",
setup.owners,
setup.threshold,
setup.to,
setup.data,
setup.fallbackHandler,
setup.paymentToken,
setup.payment,
setup.paymentReceiver
);
safe = address(SafeProxyFactory(factory).createProxyWithNonce(singleton, init, setup.saltNonce));
}

// setup the gnosis safe with 2 owners, threshold of 1.
// make the owners recognizable addrs to aid in inspecting storage layout
function getUsdcAdminSetup(address fallbackHandler) public pure returns (SafeSetup memory usdcAdminSetup) {
address[] memory owners = new address[](2);
owners[0] = OWNER_ONE;
owners[1] = OWNER_TWO;
usdcAdminSetup = SafeSetup({
owners: owners,
threshold: 1,
to: address(0),
data: "",
fallbackHandler: fallbackHandler,
paymentToken: address(0),
payment: 0,
paymentReceiver: payable(address(0)),
saltNonce: 17001
});
}

// example run:
// forge script GnosisScript --sig "printOwnerSlots" "[0x1111111111111111111111111111111111111111, 0x2222222222222222222222222222222222222222]"
function printOwnerSlots(address[] memory owners) public pure {
for (uint256 i = 0; i <= owners.length; i++) {
bytes32 value = (i == 0) ? SENTINEL_VALUE : addressToBytes32(owners[i - 1]);
bytes32 slot = keccak256(abi.encodePacked(value, uint256(2)));
console2.logBytes32(slot);
}
}

function addressToBytes32(address addr) internal pure returns (bytes32) {
return bytes32(uint256(uint160(addr)));
}
}
19 changes: 19 additions & 0 deletions script/DeployWETH9.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity 0.8.26;

// utils
import {Script, console2} from "forge-std/Script.sol";

contract WETHScript is Script {
// forge script WETHScript --sig "deployWETH9()" --rpc-url $RPC_URL --broadcast [signing args]
function deployWETH9() public returns (address weth9) {
vm.startBroadcast();

bytes memory deployCode =
hex"60606040526040805190810160405280600d81526020017f57726170706564204574686572000000000000000000000000000000000000008152506000908051906020019061004f9291906100c8565b506040805190810160405280600481526020017f57455448000000000000000000000000000000000000000000000000000000008152506001908051906020019061009b9291906100c8565b506012600260006101000a81548160ff021916908360ff16021790555034156100c357600080fd5b61016d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061010957805160ff1916838001178555610137565b82800160010185558215610137579182015b8281111561013657825182559160200191906001019061011b565b5b5090506101449190610148565b5090565b61016a91905b8082111561016657600081600090555060010161014e565b5090565b90565b610c348061017c6000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029";

assembly {
weth9 := create(0, add(deployCode, 0x20), mload(deployCode))
}
}
}
10 changes: 0 additions & 10 deletions script/Zenith.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ pragma solidity 0.8.26;
import {Zenith} from "../src/Zenith.sol";
import {Transactor} from "../src/Transactor.sol";
import {HostOrders} from "../src/orders/HostOrders.sol";
import {RollupOrders} from "../src/orders/RollupOrders.sol";
import {Passage} from "../src/passage/Passage.sol";
import {RollupPassage} from "../src/passage/RollupPassage.sol";
// utils
import {Script} from "forge-std/Script.sol";

Expand All @@ -28,14 +26,6 @@ contract ZenithScript is Script {
m = new HostOrders(permit2);
}

// deploy:
// forge script ZenithScript --sig "deployL2(address)" --rpc-url $L2_RPC_URL --private-key $PRIVATE_KEY --broadcast $PERMIT_2
function deployL2(address permit2) public returns (RollupPassage p, RollupOrders m) {
vm.startBroadcast();
p = new RollupPassage(permit2);
m = new RollupOrders(permit2);
}

// NOTE: script must be run using SequencerAdmin key
// set sequencer:
// forge script ZenithScript --sig "setSequencerRole(address,address)" --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast $ZENITH_ADDRESS $SEQUENCER_ADDRESS
Expand Down
37 changes: 37 additions & 0 deletions script/ZenithL2.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity 0.8.26;

// system contracts
import {RollupOrders} from "../src/orders/RollupOrders.sol";
import {RollupPassage} from "../src/passage/RollupPassage.sol";
// simple erc20
import {SimpleERC20} from "simple-erc20/SimpleERC20.sol";
// utils
import {Script, console2} from "forge-std/Script.sol";

// create2 address for Permit2
address constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
// address that can mint ERC20 tokens. equal to "tokenadmin" in hex.
// the Signet Node makes evm executions from this address to perform ERC20 bridge-ins.
address constant MINTER = 0x00000000000000000000746f6b656E61646d696E;

contract L2Script is Script {
// deploy:
// forge script L2Script --sig "deploySystem()" --rpc-url $RPC_URL --broadcast [signing args]
function deploySystem() public returns (address rollupPassage, address rollupOrders, address wbtc, address usdt) {
vm.startBroadcast();

// deploy system contracts
rollupPassage = address(new RollupPassage{salt: "zenith.rollupPassage"}(PERMIT2));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to do salt-mining to find low addresses?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm. well, we don't technically have to. we could handpick better addrs than we could reasonably mine by simply directly editing the allocs file. though, that would mean generating the allocs would be less reproducible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we'd also have to do some find-and-replace shenangians to update immutables and storage vars. which would be annoying. but it would be awful nice to have them have short addresses 🤔

Copy link
Contributor Author

@anna-carroll anna-carroll Sep 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

depends on how dearly we wish for the script to produce the exact final allocs

if we want efficient addrs for all contracts (&& fully deterministic script -> allocs) we might want to consider forking the USDC deploy script and making them CREATE2 deploys, because rn they're just CREATE and can't be easily mined

Copy link
Contributor Author

@anna-carroll anna-carroll Sep 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we'd also have to do some find-and-replace shenangians to update immutables and storage vars. which would be annoying. but it would be awful nice to have them have short addresses 🤔

well, actually, out of the following contracts

  • permit2
  • RollupPassage
  • RollupOrders
  • WBTC
  • USDT
  • SafeProxyFactory
  • SafeL2
  • CompatibilityFallbackHandler
  • the USDC admin Safe instance
  • WETH9

we could handpick the addrs without find-and-replacing anything in code/storage:

  1. permit2 is stored as an immutable in RollupPassage and RollupOrders
  2. SafeL2 and CompatibilityFallbackHandler are stored in the storage slots of the USDC admin Safe instance
  3. USDC admin Safe instance is stored in various storage slots in the USDC protocol

BUT, for all three of these cases, the addrs that are stored in storage/immutables are just params configured in the deploys of the subsequent contracts. we could just handpick the addrs and reconfigure the deploys to point to those addrs and the immutables/storage slots would be produced correctly by the deploy scripts.

The only ones that would be more complex to fiddle with (and therefore something I'm reticent to do) is:

  • the entire USDC protocol

which has a lot of internal dependencies on itself that is stored in immutables/storage, so we'd have to get into the guts to mess with the addresses

rollupOrders = address(new RollupOrders{salt: "zenith.rollupOrders"}(PERMIT2));

// deploy simple erc20 tokens
wbtc = address(new SimpleERC20{salt: "zenith.wbtc"}(MINTER, "Wrapped BTC", "WBTC"));
usdt = address(new SimpleERC20{salt: "zenith.usdt"}(MINTER, "Tether USD", "USDT"));
}
}

// NOTE: must deploy Permit2 via https://github.com/Uniswap/permit2/blob/main/script/DeployPermit2.s.sol
// in order to properly setup _CACHED_CHAIN_ID and _CACHED_DOMAIN_SEPARATOR

// NOTE: must deploy USDC via https://github.com/circlefin/stablecoin-evm/blob/master/scripts/deploy/deploy-fiat-token.s.sol