Skip to content
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
47 changes: 44 additions & 3 deletions deploy/111_deploy_universal_spokepool.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { DeployFunction } from "hardhat-deploy/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { deployNewProxy, getSpokePoolDeploymentInfo } from "../utils/utils.hre";
import { FILL_DEADLINE_BUFFER, L2_ADDRESS_MAP, QUOTE_TIME_BUFFER, USDC, ZERO_ADDRESS } from "./consts";
import {
EXPECTED_SAFE_ADDRESS,
FILL_DEADLINE_BUFFER,
L2_ADDRESS_MAP,
QUOTE_TIME_BUFFER,
USDC,
ZERO_ADDRESS,
} from "./consts";
import { CHAIN_IDs, PRODUCTION_NETWORKS, TOKEN_SYMBOLS_MAP } from "../utils/constants";
import { getOftEid, toWei } from "../utils/utils";
import { getOftEid, toWei, predictedSafe } from "../utils/utils";
import { getNodeUrl } from "../utils";
import { getDeployedAddress } from "../src/DeploymentUtils";
import "@nomiclabs/hardhat-ethers";
import Safe from "@safe-global/protocol-kit";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { hubPool, hubChainId, spokeChainId } = await getSpokePoolDeploymentInfo(hre);
Expand Down Expand Up @@ -53,7 +63,38 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
// target address of the spoke pool. This is because the HubPool does not pass in the chainId when calling
// relayMessage() on the Adapter. Therefore, if Universal SpokePools share the same address,
// then a message designed to be sent to one chain could be sent to another's SpokePool.
await deployNewProxy("Universal_SpokePool", constructorArgs, initArgs);
const { proxyAddress } = await deployNewProxy("Universal_SpokePool", constructorArgs, initArgs);

if (!proxyAddress) {
return;
}

const nodeUrl = getNodeUrl(spokeChainId);

const protocolKit = await Safe.init({
provider: nodeUrl,
predictedSafe,
});

const existingProtocolKit = await protocolKit.connect({
safeAddress: EXPECTED_SAFE_ADDRESS,
});
const isDeployed = await existingProtocolKit.isSafeDeployed();

if (!isDeployed) {
throw new Error("Expected Safe address is not deployed, please deploy it first");
}

const factory = await hre.ethers.getContractFactory("Universal_SpokePool");
const contract = factory.attach(proxyAddress);

const owner = await contract.owner();
if (owner !== EXPECTED_SAFE_ADDRESS) {
await (await contract.transferOwnership(EXPECTED_SAFE_ADDRESS)).wait();
console.log("Transferred ownership to Expected Safe address:", await contract.owner());
} else {
console.log("Expected Safe address is already the owner of the Universal SpokePool");
}
};
module.exports = func;
func.tags = ["UniversalSpokePool"];
10 changes: 10 additions & 0 deletions deploy/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ export const ZK_L1_GAS_TO_L2_GAS_PER_PUBDATA_LIMIT = 800;
export const ZK_L2_GAS_LIMIT = 2000000;
export const ZK_MAX_GASPRICE = "10000000000000"; // 10k gwei

// Expected Safe address for Universal SpokePool
export const EXPECTED_SAFE_ADDRESS = "0x0Fc8E2BB9bEd4FDb51a0d36f2415c4C7F9e75F6e";
export const EXPECTED_SAFE_OWNERS = [
"0x868CF19464e17F76D6419ACC802B122c22D2FD34",
"0xcc400c09ecBAC3e0033e4587BdFAABB26223e37d",
"0x837219D7a9C666F5542c4559Bf17D7B804E5c5fe",
"0x1d933Fd71FF07E69f066d50B39a7C34EB3b69F05",
"0x996267d7d1B7f5046543feDe2c2Db473Ed4f65e9",
];

export const L1_ADDRESS_MAP: { [key: number]: { [contractName: string]: string } } = {
[CHAIN_IDs.MAINNET]: {
finder: "0x40f941E48A552bF496B154Af6bf55725f18D77c3",
Expand Down
8 changes: 8 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ const config: HardhatUserConfig = {
browserURL: "https://explorer.redstone.xyz",
},
},
{
network: "plasma",
chainId: 9745,
urls: {
apiURL: "https://api.routescan.io/v2/network/mainnet/evm/9745/etherscan",
browserURL: "https://plasmascan.to",
},
},
{
network: "soneium",
chainId: CHAIN_IDs.SONEIUM,
Expand Down
24 changes: 3 additions & 21 deletions scripts/deployMultisig.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
import { getNodeUrl } from "../utils";
import { ethers } from "../utils/utils";
import { ethers, predictedSafe } from "../utils/utils";
import { hre } from "../utils/utils.hre";
import Safe, { SafeAccountConfig, PredictedSafeProps } from "@safe-global/protocol-kit";

const safeAccountConfig: SafeAccountConfig = {
owners: [
"0x868CF19464e17F76D6419ACC802B122c22D2FD34",
"0xcc400c09ecBAC3e0033e4587BdFAABB26223e37d",
"0x837219D7a9C666F5542c4559Bf17D7B804E5c5fe",
"0x1d933Fd71FF07E69f066d50B39a7C34EB3b69F05",
"0x996267d7d1B7f5046543feDe2c2Db473Ed4f65e9",
],
threshold: 2,
};
const EXPECTED_SAFE_ADDRESS = "0x0Fc8E2BB9bEd4FDb51a0d36f2415c4C7F9e75F6e";
const predictedSafe: PredictedSafeProps = {
safeAccountConfig,
safeDeploymentConfig: {
// Safe addresses are deterministic based on owners and salt nonce.
saltNonce: "0x1234",
},
};
import { EXPECTED_SAFE_ADDRESS } from "../deploy/consts";
import Safe from "@safe-global/protocol-kit";

/**
* Script to deploy a new Safe Multisig contract via the Safe SDK. Run via:
Expand Down
17 changes: 10 additions & 7 deletions utils/utils.hre.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export async function deployNewProxy(
constructorArgs: FnArgs[],
initArgs: FnArgs[],
implementationOnly?: boolean
): Promise<void> {
): Promise<{ proxyAddress?: string; implementationAddress: string }> {
const { deployments, run, upgrades, getChainId } = hre;
let chainId = Number(await getChainId());

Expand All @@ -54,11 +54,12 @@ export async function deployNewProxy(
}

// If a SpokePool can be found in deployments/deployments.json, then only deploy an implementation contract.
const proxy = getDeployedAddress("SpokePool", chainId, false);
implementationOnly ??= proxy !== undefined;
let proxyAddress = getDeployedAddress("SpokePool", chainId, false);
implementationOnly ??= proxyAddress !== undefined;
let implementationAddress: string;
if (implementationOnly) {
console.log(`${name} deployment already detected @ ${proxy}, deploying new implementation.`);
instance = (await upgrades.deployImplementation(await getContractFactory(name, {}), {
console.log(`${name} deployment already detected @ ${proxyAddress}, deploying new implementation.`);
implementationAddress = instance = (await upgrades.deployImplementation(await getContractFactory(name, {}), {
constructorArgs,
kind: "uups",
unsafeAllow: unsafeAllowArgs as unsafeAllowTypes,
Expand All @@ -71,9 +72,9 @@ export async function deployNewProxy(
constructorArgs,
initializer: "initialize",
});
instance = (await proxy.deployed()).address;
proxyAddress = instance = (await proxy.deployed()).address;
console.log(`New ${name} proxy deployed @ ${instance}`);
const implementationAddress = await upgrades.erc1967.getImplementationAddress(instance);
implementationAddress = await upgrades.erc1967.getImplementationAddress(instance);
console.log(`${name} implementation deployed @ ${implementationAddress}`);
}

Expand All @@ -93,6 +94,8 @@ export async function deployNewProxy(
// https://docs.openzeppelin.com/upgrades-plugins/1.x/api-hardhat-upgrades#verify
const contract = `contracts/${name}.sol:${name}`;
await verifyContract(instance, constructorArgs, contract);

return { proxyAddress, implementationAddress };
}

export async function verifyContract(address: string, constructorArguments: any[], contract?: string) {
Expand Down
16 changes: 15 additions & 1 deletion utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { smock, FakeContract } from "@defi-wonderland/smock";
import { FactoryOptions } from "hardhat/types";
import { ethers } from "hardhat";
import { BigNumber, Signer, Contract, ContractFactory, BaseContract } from "ethers";
import { OFT_EIDs } from "../deploy/consts";
import { EXPECTED_SAFE_OWNERS, OFT_EIDs } from "../deploy/consts";
export { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { SafeAccountConfig, PredictedSafeProps } from "@safe-global/protocol-kit";

chai.use(smock.matchers);

Expand Down Expand Up @@ -218,3 +219,16 @@ export function getOftEid(chainId: number): number {
}
return value;
}

export const safeAccountConfig: SafeAccountConfig = {
owners: EXPECTED_SAFE_OWNERS,
threshold: 2,
};

export const predictedSafe: PredictedSafeProps = {
safeAccountConfig,
safeDeploymentConfig: {
// Safe addresses are deterministic based on owners and salt nonce.
saltNonce: "0x1234",
},
};
Loading