Skip to content

Commit

Permalink
Merge remote-tracking branch 'core/master' into sync/core
Browse files Browse the repository at this point in the history
  • Loading branch information
tamtamchik committed Oct 3, 2024
2 parents 469d30e + aada422 commit adefe61
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 89 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,6 @@ DEPLOYER=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
GENESIS_TIME=1639659600
GAS_PRIORITY_FEE=1
GAS_MAX_FEE=100

# Etherscan API key for verifying contracts
ETHERSCAN_API_KEY=
5 changes: 1 addition & 4 deletions .github/workflows/release-abis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ jobs:
- name: Common setup
uses: ./.github/workflows/setup

- name: Compile contracts
run: yarn compile

- name: Extract ABIs
run: yarn extract-abis
run: yarn abis:extract

- name: Create ABIs archive
run: zip -j ABIs.zip lib/abi/*.json
Expand Down
3 changes: 3 additions & 0 deletions globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,8 @@ declare namespace NodeJS {
MAINNET_VALIDATORS_EXIT_BUS_ORACLE_ADDRESS?: string;
MAINNET_WITHDRAWAL_QUEUE_ADDRESS?: string;
MAINNET_WITHDRAWAL_VAULT_ADDRESS?: string;

/* for contract sourcecode verification with `hardhat-verify` */
ETHERSCAN_API_KEY?: string;
}
}
5 changes: 5 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { HardhatUserConfig, subtask } from "hardhat/config";

import { mochaRootHooks } from "test/hooks";

import "./tasks";

const RPC_URL: string = process.env.RPC_URL || "";
const MAINNET_FORKING_URL = process.env.MAINNET_FORKING_URL || "";
const INTEGRATION_SCRATCH_DEPLOY = process.env.INTEGRATION_SCRATCH_DEPLOY || "off";
Expand Down Expand Up @@ -75,6 +77,9 @@ const config: HardhatUserConfig = {
accounts: loadAccounts("sepolia"),
},
},
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY || "",
},
solidity: {
compilers: [
{
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"test:integration:fork:mainnet": "hardhat test test/integration/**/*.ts --network mainnet-fork --bail",
"typecheck": "tsc --noEmit",
"prepare": "husky",
"extract-abis": "ts-node scripts/utils/extract-abi.ts"
"abis:extract": "hardhat abis:extract",
"verify:deployed": "hardhat verify:deployed --no-compile"
},
"lint-staged": {
"./**/*.ts": [
Expand Down
83 changes: 0 additions & 83 deletions scripts/utils/extract-abi.ts

This file was deleted.

44 changes: 44 additions & 0 deletions tasks/extract-abis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import fs from "node:fs/promises";
import path from "node:path";

import { TASK_CLEAN, TASK_COMPILE } from "hardhat/builtin-tasks/task-names";
import { task } from "hardhat/config";
import { HardhatRuntimeEnvironment } from "hardhat/types";

import { log, yl } from "lib/log";

const ABI_OUTPUT_PATH = path.resolve(process.cwd(), "lib", "abi");
const LIDO_ARTIFACT_PREFIX = "contracts/";
const ARAGON_ARTIFACT_PATHS = [
"@aragon/apps-finance/contracts/Finance.sol:Finance",
"@aragon/apps-vault/contracts/Vault.sol:Vault",
"@aragon/apps-lido/apps/voting/contracts/Voting.sol:Voting",
"@aragon/apps-lido/apps/token-manager/contracts/TokenManager.sol:TokenManager",
];

const SKIP_NAMES_REGEX = /(Mock|Harness|test_helpers|Imports|deposit_contract|Pausable|.dbg.json|build-info)/;

task("abis:extract", "Extract ABIs from artifacts").setAction(async (_: unknown, hre: HardhatRuntimeEnvironment) => {
await hre.run(TASK_CLEAN);
await hre.run(TASK_COMPILE);

const artifactNames = await hre.artifacts.getAllFullyQualifiedNames();

const artifactNamesToPublish = artifactNames
.filter((name) => !SKIP_NAMES_REGEX.test(name) && name.startsWith(LIDO_ARTIFACT_PREFIX))
.concat(ARAGON_ARTIFACT_PATHS);

await fs.rm(ABI_OUTPUT_PATH, { recursive: true, force: true });
await fs.mkdir(ABI_OUTPUT_PATH, { recursive: true });

for (const name of artifactNamesToPublish) {
const artifact = await hre.artifacts.readArtifact(name);
if (artifact.abi && artifact.abi.length > 0) {
const abiData = JSON.stringify(artifact.abi, null, 2);
await fs.writeFile(path.join(ABI_OUTPUT_PATH, `${artifact.contractName}.json`), abiData);
log.success(`ABI for ${yl(artifact.contractName)} has been saved!`);
}
}

log.success("All ABIs have been extracted and saved!");
});
2 changes: 2 additions & 0 deletions tasks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./verify-contracts";
export * from "./extract-abis";
90 changes: 90 additions & 0 deletions tasks/verify-contracts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import fs from "node:fs/promises";
import path from "node:path";

import { task } from "hardhat/config";
import { HardhatRuntimeEnvironment } from "hardhat/types";

import { cy, log, yl } from "lib/log";

type DeployedContract = {
contract: string;
address: string;
constructorArgs: unknown[];
};

type ProxyContract = {
proxy: DeployedContract;
implementation: DeployedContract;
};

type Contract = DeployedContract | ProxyContract;

type NetworkState = {
deployer: string;
[key: string]: Contract | string | number;
};

const errors = [] as string[];

task("verify:deployed", "Verifies deployed contracts based on state file").setAction(
async (_: unknown, hre: HardhatRuntimeEnvironment) => {
try {
const network = hre.network.name;
log("Verifying contracts for network:", network);

const networkStateFile = `deployed-${network}.json`;
const networkStateFilePath = path.resolve("./", networkStateFile);
const data = await fs.readFile(networkStateFilePath, "utf8");
const networkState = JSON.parse(data) as NetworkState;

const deployedContracts = Object.values(networkState)
.filter((contract): contract is Contract => typeof contract === "object")
.flatMap(getDeployedContract);

// Not using Promise.all to avoid logging messages out of order
for (const contract of deployedContracts) {
await verifyContract(contract, hre);
}
} catch (error) {
log.error("Error verifying deployed contracts:", error as Error);
throw error;
}

if (errors.length > 0) {
log.error(`Failed to verify ${errors.length} contract(s):`, errors as string[]);
process.exitCode = errors.length;
}
},
);

async function verifyContract(contract: DeployedContract, hre: HardhatRuntimeEnvironment) {
const contractName = contract.contract.split("/").pop()?.split(".")[0];
const verificationParams = {
address: contract.address,
constructorArguments: contract.constructorArgs,
contract: `${contract.contract}:${contractName}`,
};

log.withArguments(
`Verifying contract: ${yl(contract.contract)} at ${cy(contract.address)} with constructor args `,
verificationParams.constructorArguments as string[],
);

try {
await hre.run("verify:verify", verificationParams);
log.success(`Successfully verified ${yl(contract.contract)}!`);
} catch (error) {
log.error(`Failed to verify ${yl(contract.contract)}:`, error as Error);
errors.push(verificationParams.address);
}
log.emptyLine();
}

function getDeployedContract(contract: Contract): DeployedContract[] {
if ("proxy" in contract && "implementation" in contract) {
return [contract.proxy, contract.implementation];
} else if ("contract" in contract && "address" in contract && "constructorArgs" in contract) {
return [contract];
}
return [];
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
"typechain-types": ["./typechain-types"]
}
},
"include": ["./test", "./typechain-types", "./lib", "./scripts", "./deployed-*.json"],
"include": ["./test", "./typechain-types", "./lib", "./scripts", "./tasks", "./deployed-*.json"],
"files": ["./hardhat.config.ts", "./commitlint.config.ts", "./globals.d.ts"]
}

0 comments on commit adefe61

Please sign in to comment.