Skip to content
This repository has been archived by the owner on Oct 6, 2023. It is now read-only.

Commit

Permalink
AP-743: Deployment Script: Logging of TX Hashes (#370)
Browse files Browse the repository at this point in the history
* Add generic deploy contract function

* Update getContractName to accept types as well

* Update Diamond-related tasks to use new 'deploy' script

* Small refactor in cutDiamond

* Refactor deploy

* Add deployBehindProxy helper

* Make deploy and deployBehindProxy accept factory instance

* Revert change to utils/getContractName.ts

* Partial: update Deployment to the deploy's generic Deployment<T> type

* Create ProxyDeployment type

* Split deploy registrar and local registrar scripts

* Add dividers to deploy(BehindProxy

* Partial: update deployments called in deployAngelProtocl up to deployIndexFund

* Update all scripts to use new deploy and deployBehindProxy helpers

* Move env.config to config/

* Set types/ as one of root files in tsconfig.json

* Update all types imports in tasks/scripts

* Add divider at the end of 'deploy'

* Move CONFIG into separate config.ts file

* Revert contract-address.json

* Revert "Move CONFIG into separate config.ts file"

This reverts commit 1812364.

* Revert "Add divider at the end of 'deploy'"

This reverts commit 0a473f4.

* Remove divider from deploy

* Update error handling

* Remove unnecessary changes
  • Loading branch information
Nenad Misic authored Sep 7, 2023
1 parent c9bfe25 commit b03cf59
Show file tree
Hide file tree
Showing 82 changed files with 675 additions and 877 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion config/fees.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {FeeTypes} from "../types";
import {Fees} from "./types";
import {FeeTypes} from "../utils";

export const FEES: Fees = {
[FeeTypes.Default]: {
Expand Down
1 change: 1 addition & 0 deletions config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,5 @@ export const CONFIG: Config = {
},
};

export * from "./env.config";
export * from "./fees";
14 changes: 13 additions & 1 deletion config/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {BigNumber} from "ethers";
import {FeeTypes} from "types";
import {AddressObj} from "../utils";
import {FeeTypes} from "../utils";

export type Config = {
AP_TEAM_MULTISIG_DATA: {
Expand Down Expand Up @@ -61,3 +61,15 @@ export type Fees = {
bps: number;
};
};

export type EnvConfig = {
ETHERSCAN_API_KEY: string;
GANACHE_PRIVATE_KEY: string;
GANACHE_RPC_URL: string;
GOERLI_RPC_URL: string;
MAINNET_RPC_URL: string;
MUMBAI_RPC_URL: string;
POLYGON_RPC_URL: string;
POLYSCAN_API_KEY: string;
ACCOUNTS: string[];
};
38 changes: 12 additions & 26 deletions contracts/accessory/gift-cards/scripts/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {HardhatRuntimeEnvironment} from "hardhat/types";
import {getContractName, getSigners, logger, updateAddresses, verify} from "utils";
import {GiftCards__factory} from "typechain-types";
import {GiftCardsMessage} from "typechain-types/contracts/accessory/gift-cards/GiftCards";
import {GiftCards__factory, ProxyContract__factory} from "typechain-types";
import {deployBehindProxy, getSigners, updateAddresses, verify} from "utils";

export async function deployGiftCard(
GiftCardsDataInput: GiftCardsMessage.InstantiateMsgStruct,
Expand All @@ -12,43 +12,29 @@ export async function deployGiftCard(
try {
const {deployer} = await getSigners(hre);

// data setup
const GiftCards = new GiftCards__factory(deployer);
const GiftCardsInstance = await GiftCards.deploy();
await GiftCardsInstance.deployed();
logger.out(`GiftCards implementation address: ${GiftCardsInstance.address}"`);
const initData = GiftCards.interface.encodeFunctionData("initialize", [GiftCardsDataInput]);
// deploy
const {implementation, proxy} = await deployBehindProxy(GiftCards, admin, initData);

const ProxyContract = new ProxyContract__factory(deployer);
const GiftCardsData = GiftCardsInstance.interface.encodeFunctionData("initialize", [
GiftCardsDataInput,
]);
const GiftCardsProxy = await ProxyContract.deploy(
GiftCardsInstance.address,
admin,
GiftCardsData
);
await GiftCardsProxy.deployed();
logger.out(`GiftCards Address (Proxy): ${GiftCardsProxy.address}"`);

// update address file & verify contracts
// update address file
await updateAddresses(
{
giftcards: {
proxy: GiftCardsProxy.address,
implementation: GiftCardsInstance.address,
proxy: proxy.contract.address,
implementation: implementation.contract.address,
},
},
hre
);

if (verify_contracts) {
await verify(hre, {
address: GiftCardsProxy.address,
constructorArguments: [GiftCardsInstance.address, admin, GiftCardsData],
contractName: getContractName(GiftCards),
});
await verify(hre, implementation);
await verify(hre, proxy);
}

return Promise.resolve(GiftCardsProxy.address);
return Promise.resolve(proxy.contract.address);
} catch (error) {
return Promise.reject(error);
}
Expand Down
16 changes: 7 additions & 9 deletions contracts/core/accounts/scripts/deploy/cutDiamond.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@ export default async function cutDiamond(
networkName,
]);

const cuts = facetCuts.map((x) => x.cut);
const tx = await diamondCut.diamondCut(cuts, diamondInit, calldata);
logger.out(`Cutting Diamond tx: ${tx.hash}`);

const receipt = await hre.ethers.provider.waitForTransaction(tx.hash);

if (!receipt.status) {
throw new Error(`Diamond cut failed: ${tx.hash}`);
}
const tx = await diamondCut.diamondCut(
facetCuts.map((x) => x.cut),
diamondInit,
calldata
);
logger.out(`Tx hash: ${tx.hash}`);
await tx.wait();

logger.out("Completed Diamond cut.");
}
80 changes: 39 additions & 41 deletions contracts/core/accounts/scripts/deploy/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {SignerWithAddress} from "@nomiclabs/hardhat-ethers/signers";
import {ContractFactory} from "ethers";
import {HardhatRuntimeEnvironment} from "hardhat/types";
import {
DiamondCutFacet__factory,
DiamondInit__factory,
Diamond__factory,
IERC173__factory,
} from "typechain-types";
import {Deployment, getContractName, logger, updateAddresses} from "utils";
import {Deployment} from "types";
import {deploy, logger, updateAddresses} from "utils";
import cutDiamond from "./cutDiamond";
import deployFacets from "./deployFacets";

Expand All @@ -17,8 +19,8 @@ export async function deployAccountsDiamond(
deployer: SignerWithAddress,
hre: HardhatRuntimeEnvironment
): Promise<{
diamond: Deployment;
facets: Array<Deployment>;
diamond: Deployment<Diamond__factory>;
facets: Array<Deployment<ContractFactory>>;
}> {
logger.out("Deploying and setting up Accounts Diamond and all its facets...");

Expand All @@ -28,54 +30,53 @@ export async function deployAccountsDiamond(

const cuts = await deployFacets(deployer, hre);

await cutDiamond(diamond.address, diamondInit.address, deployer, owner, registrar, cuts, hre);
await cutDiamond(
diamond.contract.address,
diamondInit.contract.address,
deployer,
owner,
registrar,
cuts,
hre
);

await setDiamondContractOwner(diamond.address, diamondAdmin, deployer);
await setDiamondContractOwner(diamond.contract.address, diamondAdmin, deployer);

return {
diamond,
facets: cuts
.map<Deployment>(({cut, facetName}) => ({
address: cut.facetAddress.toString(),
contractName: facetName,
}))
.map<Deployment<ContractFactory>>((facetCut) => facetCut.deployment)
.concat(diamondCutFacet, diamondInit),
};
}

async function deployDiamond(
deployer: SignerWithAddress,
hre: HardhatRuntimeEnvironment
): Promise<{diamond: Deployment; diamondCutFacet: Deployment}> {
const DiamondCutFacet = new DiamondCutFacet__factory(deployer);
const diamondCutFacet = await DiamondCutFacet.deploy();
await diamondCutFacet.deployed();
logger.out(`DiamondCutFacet deployed at: ${diamondCutFacet.address}`);
): Promise<{
diamond: Deployment<Diamond__factory>;
diamondCutFacet: Deployment<DiamondCutFacet__factory>;
}> {
const diamondCutFacet = await deploy(new DiamondCutFacet__factory(deployer));

const constructorArguments: Parameters<Diamond__factory["deploy"]> = [
const diamond = await deploy(new Diamond__factory(deployer), [
deployer.address,
diamondCutFacet.address,
];
const Diamond = new Diamond__factory(deployer);
const diamond = await Diamond.deploy(...constructorArguments);
await diamond.deployed();
logger.out(`Diamond deployed at: ${diamond.address}`);
diamondCutFacet.contract.address,
]);

await updateAddresses(
{accounts: {diamond: diamond.address, facets: {diamondCutFacet: diamondCutFacet.address}}},
{
accounts: {
diamond: diamond.contract.address,
facets: {diamondCutFacet: diamondCutFacet.contract.address},
},
},
hre
);

return {
diamond: {
address: diamond.address,
contractName: getContractName(Diamond),
constructorArguments,
},
diamondCutFacet: {
address: diamondCutFacet.address,
contractName: getContractName(DiamondCutFacet),
},
diamond,
diamondCutFacet,
};
}

Expand All @@ -87,18 +88,15 @@ async function deployDiamond(
async function deployDiamondInit(
admin: SignerWithAddress,
hre: HardhatRuntimeEnvironment
): Promise<Deployment> {
const DiamondInit = new DiamondInit__factory(admin);
const diamondInit = await DiamondInit.deploy();
await diamondInit.deployed();
logger.out(`DiamondInit deployed at: ${diamondInit.address}`);
): Promise<Deployment<DiamondInit__factory>> {
const diamondInit = await deploy(new DiamondInit__factory(admin));

await updateAddresses({accounts: {facets: {diamondInitFacet: diamondInit.address}}}, hre);
await updateAddresses(
{accounts: {facets: {diamondInitFacet: diamondInit.contract.address}}},
hre
);

return {
address: diamondInit.address,
contractName: getContractName(DiamondInit),
};
return diamondInit;
}

async function setDiamondContractOwner(
Expand Down
20 changes: 10 additions & 10 deletions contracts/core/accounts/scripts/deploy/deployFacets.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {SignerWithAddress} from "@nomiclabs/hardhat-ethers/signers";
import {HardhatRuntimeEnvironment} from "hardhat/types";
import {getContractName, logger, updateAddresses} from "utils";
import {deploy, logger, updateAddresses} from "utils";
import {FacetCutAction, getSelectors} from "../libraries/diamond";
import getFacetFactoryEntries from "./getFacetFactoryEntries";
import {FacetCut} from "./types";
Expand All @@ -16,24 +16,24 @@ export default async function deployFacets(
const factoryEntries = getFacetFactoryEntries(diamondOwner);

for (const entry of factoryEntries) {
const contractName = getContractName(entry.factory);
try {
const facet = await entry.factory.deploy();
await facet.deployed();
logger.out(`${contractName} deployed at: ${facet.address}`);
const deployment = await deploy(entry.factory);

await updateAddresses({accounts: {facets: {[entry.addressField]: facet.address}}}, hre);
await updateAddresses(
{accounts: {facets: {[entry.addressField]: deployment.contract.address}}},
hre
);

cuts.push({
facetName: contractName,
deployment: deployment,
cut: {
facetAddress: facet.address,
facetAddress: deployment.contract.address,
action: FacetCutAction.Add,
functionSelectors: getSelectors(facet),
functionSelectors: getSelectors(deployment.contract),
},
});
} catch (error) {
logger.out(`Failed to deploy ${contractName}, reason: ${error}`, logger.Level.Error);
logger.out(`Deployment failed, reason: ${error}`, logger.Level.Error);
}
}

Expand Down
7 changes: 6 additions & 1 deletion contracts/core/accounts/scripts/deploy/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import {ContractFactory} from "ethers";
import {IDiamondCut} from "typechain-types";
import {Deployment} from "types";

export type FacetCut = {facetName: string; cut: IDiamondCut.FacetCutStruct};
export type FacetCut = {
deployment: Deployment<ContractFactory>;
cut: IDiamondCut.FacetCutStruct;
};
51 changes: 21 additions & 30 deletions contracts/core/gasFwd/scripts/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,49 @@
import {SignerWithAddress} from "@nomiclabs/hardhat-ethers/signers";
import {HardhatRuntimeEnvironment} from "hardhat/types";
import {GasFwdFactory__factory, GasFwd__factory} from "typechain-types";
import {Deployment, getAddresses, getContractName, logger, updateAddresses} from "utils";
import {Deployment} from "types";
import {deploy, logger, updateAddresses} from "utils";

type Data = {
deployer: SignerWithAddress;
proxyAdmin: string;
factoryOwner: string;
registrar?: string;
registrar: string;
};

export async function deployGasFwd(
{deployer, proxyAdmin, factoryOwner, registrar}: Data,
hre: HardhatRuntimeEnvironment
): Promise<{factory: Deployment; implementation: Deployment}> {
logger.out("Deploying Gas Forwarder...");

logger.out("Deploying GasFwd implementation...");
const GF = new GasFwd__factory(deployer);
const gf = await GF.deploy();
await gf.deployed();
logger.out(`Address: ${gf.address}`);

const addresses = await getAddresses(hre);
let registrarAddress = registrar ? registrar : addresses.registrar.proxy;

logger.out("Deploying factory...");
const GFF = new GasFwdFactory__factory(deployer);
const constructorArguments: Parameters<GasFwdFactory__factory["deploy"]> = [
gf.address,
): Promise<{
factory: Deployment<GasFwdFactory__factory>;
implementation: Deployment<GasFwd__factory>;
}> {
const implementation = await deploy(new GasFwd__factory(deployer));

const factory = await deploy(new GasFwdFactory__factory(deployer), [
implementation.contract.address,
proxyAdmin,
registrarAddress,
];
const gff = await GFF.deploy(...constructorArguments);
await gff.deployed();
logger.out(`Address: ${gff.address}`);
registrar,
]);

logger.out(`Transferring ownership to: ${factoryOwner}...`);
const tx = await gff.transferOwnership(factoryOwner);
const tx = await factory.contract.transferOwnership(factoryOwner);
logger.out(`Tx hash: ${tx.hash}`);
await tx.wait();
const newOwner = await factory.contract.owner();
if (newOwner !== factoryOwner) {
throw new Error(`Error updating owner: expected '${factoryOwner}', actual: '${newOwner}'`);
}

await updateAddresses(
{
gasFwd: {
implementation: gf.address,
factory: gff.address,
implementation: implementation.contract.address,
factory: factory.contract.address,
},
},
hre
);

return {
implementation: {address: gf.address, contractName: getContractName(GF)},
factory: {address: gff.address, contractName: getContractName(GFF), constructorArguments},
};
return {implementation, factory};
}
Loading

0 comments on commit b03cf59

Please sign in to comment.