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

feat: simplify protocol contracts deployment #112

Merged
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
10 changes: 5 additions & 5 deletions data/addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@
"zetaTokenConsumerUniV3": ""
},
"eth_mainnet": {
"connector": "0x054197b11aA98E6d842073F9362b64b10F2c24A7",
"erc20Custody": "0xb77277Cf4c734894d4f2471492B184E5C71C32a9",
"connector": "0x000007Cf399229b2f5A4D043F20E90C9C98B7C6a",
"erc20Custody": "0x000001b91C19A31809e769110d35FAd2C15BCeA7",
"immutableCreate2Factory": "0x095a03c6a68137fE9a566bBc3e552F299d8b886d",
"tss": "0x6F28967E382765cEF6149fa02Cd0Ba0753B01A6b",
"tssUpdater": "0xfCA0392567D5eb77681843b2608dE9C625F57948",
"zetaToken": "0x5CDf9f824526Bf2A4638BF6879591F635Bb8f0B8"
"tss": "0xaeB6dDB7708467814D557e340283248be8E43124",
"tssUpdater": "0xaeB6dDB7708467814D557e340283248be8E43124",
"zetaToken": "0xf091867EC603A6628eD83D274E835539D82e9cc8"
},
"goerli_testnet": {
"connector": "0x00005e3125aba53c5652f9f0ce1a4cf91d8b15ea",
Expand Down
3 changes: 2 additions & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "@nomiclabs/hardhat-waffle";
import "@nomiclabs/hardhat-etherscan";
import "@nomicfoundation/hardhat-verify";
import "@typechain/hardhat";
import "tsconfig-paths/register";
import "hardhat-abi-exporter";
Expand All @@ -15,6 +15,7 @@ const config: HardhatUserConfig = {
etherscan: {
apiKey: {
// BSC
bsc: process.env.BSCSCAN_API_KEY || "",
bscTestnet: process.env.BSCSCAN_API_KEY || "",
// ETH
goerli: process.env.ETHERSCAN_API_KEY || "",
Expand Down
68 changes: 59 additions & 9 deletions lib/contracts.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,66 @@ export const ZETA_INITIAL_SUPPLY = 2_100_000_000;
export const MAX_ETH_ADDRESS = "0xffffffffffffffffffffffffffffffffffffffff";

// dev: this values should be calculated using get-salt script
export const ZETA_TOKEN_SALT_NUMBER_ETH = "84108";
export const ZETA_TOKEN_SALT_NUMBER_NON_ETH = "29265";
const SALT_NUMBERS = {
baobab_testnet: {
zetaConnector: "71733",
zetaConsumer: "0",
zetaERC20Custody: "195084",
zetaToken: "29265",
},
bsc_mainnet: {
zetaConnector: "71733",
zetaConsumer: "0",
zetaERC20Custody: "195084",
zetaToken: "29265",
},
bsc_testnet: {
zetaConnector: "71733",
zetaConsumer: "0",
zetaERC20Custody: "195084",
zetaToken: "29265",
},
btc_testnet: {
zetaConnector: "",
zetaConsumer: "",
zetaERC20Custody: "",
zetaToken: "",
},
eth_mainnet: {
zetaConnector: "84286",
zetaConsumer: "0",
zetaERC20Custody: "926526",
zetaToken: "0",
},
goerli_testnet: {
zetaConnector: "1414",
zetaConsumer: "0",
zetaERC20Custody: "87967",
zetaToken: "84108",
},
mumbai_testnet: {
zetaConnector: "71733",
zetaConsumer: "0",
zetaERC20Custody: "195084",
zetaToken: "29265",
},
zeta_testnet: {
zetaConnector: "71733",
zetaConsumer: "0",
zetaERC20Custody: "195084",
zetaToken: "29265",
},
};

// dev: this values should be calculated using get-salt script
export const ZETA_CONNECTOR_SALT_NUMBER_ETH = "1414";
export const ZETA_CONNECTOR_SALT_NUMBER_NON_ETH = "71733";
export const getSaltNumber = (contractName: string, networkName: string) => {
const saltNumber = SALT_NUMBERS[networkName][contractName];

if (!saltNumber) {
throw new Error(`Salt number for ${contractName} on ${networkName} is not defined.`);
}

return saltNumber;
};

export const ERC20_CUSTODY_SALT_NUMBER_ETH = "87967";
export const ERC20_CUSTODY_SALT_NUMBER_NON_ETH = "195084";
export const ERC20_CUSTODY_ZETA_FEE = "0";
export const ERC20_CUSTODY_ZETA_MAX_FEE = parseEther("1000");

export const ZETA_CONSUMER_SALT_NUMBER = "0";
5 changes: 1 addition & 4 deletions lib/contracts.helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ import { BaseContract, ContractFactory } from "ethers";
import { ethers } from "hardhat";

export const isEthNetworkName = (networkName: string) =>
networkName === "eth-localnet" ||
networkName === "goerli_testnet" ||
networkName === "eth_mainnet" ||
networkName === "bsc_mainnet";
networkName === "eth-localnet" || networkName === "goerli_testnet" || networkName === "eth_mainnet";

export const deployZetaConnectorBase = async ({ args }: { args: Parameters<ZetaConnectorBaseFactory["deploy"]> }) => {
const Factory = (await ethers.getContractFactory("ZetaConnectorBase")) as ZetaConnectorBaseFactory;
Expand Down
8 changes: 5 additions & 3 deletions lib/deterministic-deploy.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { BigNumber } from "ethers";
import { getAddress } from "lib";

import { getAddress } from "../lib/address.helpers";
import { MAX_ETH_ADDRESS } from "../lib/contracts.constants";
import {
buildBytecode,
buildCreate2Address,
saltToHex,
} from "../lib/ImmutableCreate2Factory/ImmutableCreate2Factory.helpers";
import { ZetaProtocolNetwork } from "./address.tools";

export const calculateBestSalt = async (
maxIterations: BigNumber,
deployerAddress: string,
constructorTypes: string[],
constructorArgs: string[],
contractBytecode: string
contractBytecode: string,
network: ZetaProtocolNetwork
) => {
const immutableCreate2Factory = getAddress("immutableCreate2Factory");
const immutableCreate2Factory = getAddress("immutableCreate2Factory", network);

let minAddress = MAX_ETH_ADDRESS;
let minAddressSalt = "";
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
"@nomicfoundation/hardhat-toolbox": "^2.0.0",
"@nomiclabs/hardhat-ethers": "^2.0.5",
"@nomiclabs/hardhat-etherscan": "3.0.3",
"@nomicfoundation/hardhat-verify": "2.0.3",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"@openzeppelin/contracts": "^4.8.3",
"@typechain/ethers-v5": "^10.1.0",
Expand Down
23 changes: 6 additions & 17 deletions scripts/deployments/core/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
import { network } from "hardhat";

import { isProtocolNetworkName } from "../../../lib/address.tools";
import { isEthNetworkName } from "../../../lib/contracts.helpers";
import { setZetaAddresses } from "../../tools/set-zeta-token-addresses";
import { deployZetaConnector } from "./deploy-zeta-connector";
import { deployZetaToken } from "./deploy-zeta-token";
import { deterministicDeployERC20Custody } from "./deterministic-deploy-erc20-custody";
import { deterministicDeployZetaConnector } from "./deterministic-deploy-zeta-connector";
import { deterministicDeployZetaToken } from "./deterministic-deploy-zeta-token";

const networkName = network.name;

async function main() {
if (!isProtocolNetworkName(networkName)) throw new Error("Invalid network name");

const zetaTokenAddress = await deployZetaToken();
const connectorAddress = await deployZetaConnector();

/**
* @description The Eth implementation of Zeta token doesn't need any address
*/
if (isEthNetworkName(network.name)) return;

/**
* @description Avoid setting Zeta addresses for local network,
* since it must be done after starting the local Zeta node
*/
await setZetaAddresses(connectorAddress, zetaTokenAddress);
await deterministicDeployZetaToken();
await deterministicDeployZetaConnector();
await deterministicDeployERC20Custody();
}

main()
Expand Down
15 changes: 7 additions & 8 deletions scripts/deployments/core/deterministic-deploy-erc20-custody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@ import { BigNumber } from "ethers";
import { ethers, network } from "hardhat";
import { getAddress, isProtocolNetworkName } from "lib";

import {
ERC20_CUSTODY_SALT_NUMBER_ETH,
ERC20_CUSTODY_SALT_NUMBER_NON_ETH,
ERC20_CUSTODY_ZETA_FEE,
ERC20_CUSTODY_ZETA_MAX_FEE,
} from "../../../lib/contracts.constants";
import { isEthNetworkName } from "../../../lib/contracts.helpers";
import { ERC20_CUSTODY_ZETA_FEE, ERC20_CUSTODY_ZETA_MAX_FEE, getSaltNumber } from "../../../lib/contracts.constants";
import {
deployContractToAddress,
saltToHex,
Expand All @@ -22,6 +16,7 @@ export const deterministicDeployERC20Custody = async () => {

const accounts = await ethers.getSigners();
const [signer] = accounts;
const initialBalance = await signer.getBalance();

const DEPLOYER_ADDRESS = process.env.DEPLOYER_ADDRESS || signer.address;

Expand All @@ -30,7 +25,7 @@ export const deterministicDeployERC20Custody = async () => {
const tssUpdaterAddress = getAddress("tssUpdater", network.name);
const immutableCreate2FactoryAddress = getAddress("immutableCreate2Factory", network.name);

const saltNumber = isEthNetworkName(network.name) ? ERC20_CUSTODY_SALT_NUMBER_ETH : ERC20_CUSTODY_SALT_NUMBER_NON_ETH;
const saltNumber = getSaltNumber("zetaERC20Custody", network.name);
const saltStr = BigNumber.from(saltNumber).toHexString();

const zetaFee = ERC20_CUSTODY_ZETA_FEE;
Expand All @@ -52,8 +47,12 @@ export const deterministicDeployERC20Custody = async () => {
signer,
});

const finalBalance = await signer.getBalance();
console.log("Deployed ERC20 Custody. Address:", address);
console.log("Constructor Args", constructorArgs);
console.log("ETH spent:", initialBalance.sub(finalBalance).toString());

return address;
};

if (!process.env.EXECUTE_PROGRAMMATICALLY) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ import { BigNumber } from "ethers";
import { ethers, network } from "hardhat";
import { getAddress, isProtocolNetworkName } from "lib";

import { ZETA_CONNECTOR_SALT_NUMBER_ETH, ZETA_CONNECTOR_SALT_NUMBER_NON_ETH } from "../../../lib/contracts.constants";
import { getSaltNumber } from "../../../lib/contracts.constants";
import { isEthNetworkName } from "../../../lib/contracts.helpers";
import {
deployContractToAddress,
saltToHex,
} from "../../../lib/ImmutableCreate2Factory/ImmutableCreate2Factory.helpers";
import { ZetaConnectorEth__factory, ZetaConnectorNonEth__factory } from "../../../typechain-types";

export async function deterministicDeployZetaConnector() {
export const deterministicDeployZetaConnector = async () => {
if (!isProtocolNetworkName(network.name)) {
throw new Error(`network.name: ${network.name} isn't supported.`);
}

const accounts = await ethers.getSigners();
const [signer] = accounts;
const initialBalance = await signer.getBalance();

const DEPLOYER_ADDRESS = process.env.DEPLOYER_ADDRESS || signer.address;

Expand All @@ -25,9 +26,7 @@ export async function deterministicDeployZetaConnector() {
const tssUpdaterAddress = getAddress("tssUpdater", network.name);
const immutableCreate2FactoryAddress = getAddress("immutableCreate2Factory", network.name);

const saltNumber = isEthNetworkName(network.name)
? ZETA_CONNECTOR_SALT_NUMBER_ETH
: ZETA_CONNECTOR_SALT_NUMBER_NON_ETH;
const saltNumber = getSaltNumber("zetaConnector", network.name);
const saltStr = BigNumber.from(saltNumber).toHexString();

const salthex = saltToHex(saltStr, DEPLOYER_ADDRESS);
Expand All @@ -50,9 +49,13 @@ export async function deterministicDeployZetaConnector() {
signer,
});

const finalBalance = await signer.getBalance();
console.log("Deployed ZetaConnector. Address:", address);
console.log("Constructor Args", constructorArgs);
}
console.log("ETH spent:", initialBalance.sub(finalBalance).toString());

return address;
};

if (!process.env.EXECUTE_PROGRAMMATICALLY) {
deterministicDeployZetaConnector()
Expand Down
17 changes: 9 additions & 8 deletions scripts/deployments/core/deterministic-deploy-zeta-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,30 @@ import { BigNumber } from "ethers";
import { ethers, network } from "hardhat";
import { getAddress, isProtocolNetworkName } from "lib";

import {
ZETA_INITIAL_SUPPLY,
ZETA_TOKEN_SALT_NUMBER_ETH,
ZETA_TOKEN_SALT_NUMBER_NON_ETH,
} from "../../../lib/contracts.constants";
import { getSaltNumber, ZETA_INITIAL_SUPPLY } from "../../../lib/contracts.constants";
import { isEthNetworkName } from "../../../lib/contracts.helpers";
import {
deployContractToAddress,
saltToHex,
} from "../../../lib/ImmutableCreate2Factory/ImmutableCreate2Factory.helpers";
import { ZetaEth__factory, ZetaNonEth__factory } from "../../../typechain-types";

export async function deterministicDeployZetaToken() {
export const deterministicDeployZetaToken = async () => {
if (!isProtocolNetworkName(network.name)) {
throw new Error(`network.name: ${network.name} isn't supported.`);
}

const accounts = await ethers.getSigners();
const [signer] = accounts;
const initialBalance = await signer.getBalance();

const DEPLOYER_ADDRESS = process.env.DEPLOYER_ADDRESS || signer.address;

const tssAddress = getAddress("tss", network.name);
const tssUpdaterAddress = getAddress("tssUpdater", network.name);
const immutableCreate2FactoryAddress = getAddress("immutableCreate2Factory", network.name);

const saltNumber = isEthNetworkName(network.name) ? ZETA_TOKEN_SALT_NUMBER_ETH : ZETA_TOKEN_SALT_NUMBER_NON_ETH;
const saltNumber = getSaltNumber("zetaToken", network.name);
const saltStr = BigNumber.from(saltNumber).toHexString();

const salthex = saltToHex(saltStr, DEPLOYER_ADDRESS);
Expand Down Expand Up @@ -57,9 +54,13 @@ export async function deterministicDeployZetaToken() {
signer,
});

const finalBalance = await signer.getBalance();
console.log("Deployed zetaToken. Address:", address);
console.log("Constructor Args", constructorArgs);
}
console.log("ETH spent:", initialBalance.sub(finalBalance).toString());

return address;
};

if (!process.env.EXECUTE_PROGRAMMATICALLY) {
deterministicDeployZetaToken()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,19 @@ export const deterministicDeployGetSaltERC20Custody = async () => {
const constructorArgs = [tssAddress, tssUpdaterAddress, zetaFee.toString(), zetaMaxFee.toString(), zetaTokenAddress];
const contractBytecode = ERC20Custody__factory.bytecode;

calculateBestSalt(MAX_ITERATIONS, DEPLOYER_ADDRESS, constructorTypes, constructorArgs, contractBytecode);
await calculateBestSalt(
MAX_ITERATIONS,
DEPLOYER_ADDRESS,
constructorTypes,
constructorArgs,
contractBytecode,
network.name
);
};

if (!process.env.EXECUTE_PROGRAMMATICALLY) {
deterministicDeployGetSaltERC20Custody()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
}
deterministicDeployGetSaltERC20Custody()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,19 @@ export async function deterministicDeployGetSaltZetaConnector() {
contractBytecode = ZetaConnectorNonEth__factory.bytecode;
}

calculateBestSalt(MAX_ITERATIONS, DEPLOYER_ADDRESS, constructorTypes, constructorArgs, contractBytecode);
await calculateBestSalt(
MAX_ITERATIONS,
DEPLOYER_ADDRESS,
constructorTypes,
constructorArgs,
contractBytecode,
network.name
);
}

if (!process.env.EXECUTE_PROGRAMMATICALLY) {
deterministicDeployGetSaltZetaConnector()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
}
deterministicDeployGetSaltZetaConnector()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Loading
Loading