diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a88c3d..1c2736f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Version 2.1.2 + +* Added deployment arguments validation before the contract deployment. + ## Version 2.1.1 * Fixed a bug related to the shallow copying and mutation of arguments within the `getMethodString` function. diff --git a/package-lock.json b/package-lock.json index 6124e04..c0b9df1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@solarity/hardhat-migrate", - "version": "2.1.1", + "version": "2.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@solarity/hardhat-migrate", - "version": "2.1.1", + "version": "2.1.2", "hasInstallScript": true, "license": "MIT", "workspaces": [ diff --git a/package.json b/package.json index 2e4ebfd..4d105b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solarity/hardhat-migrate", - "version": "2.1.1", + "version": "2.1.2", "description": "Automatic deployment and verification of smart contracts", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", diff --git a/src/deployer/MinimalContract.ts b/src/deployer/MinimalContract.ts index 4a2bf25..ec07974 100644 --- a/src/deployer/MinimalContract.ts +++ b/src/deployer/MinimalContract.ts @@ -139,6 +139,14 @@ export class MinimalContract { return; } + const factory = new ethers.ContractFactory(this._interface, this._bytecode); + + const coder = new ethers.AbiCoder(); + // Try to encode the arguments before sending the deployment transaction + factory.interface.deploy.inputs.forEach((input, idx) => { + coder.encode([input], [args[idx]]); + }); + VerificationProcessor.saveVerificationFunction({ contractAddress, contractName: contractName, diff --git a/src/utils/common.ts b/src/utils/common.ts index 27a334c..7389d60 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -1,5 +1,6 @@ import { join } from "path"; import { realpathSync, existsSync } from "fs"; + import { UNKNOWN_CONTRACT_NAME } from "../constants"; export function resolvePathToFile(path: string, file: string = ""): string { diff --git a/test/fixture-projects/hardhat-project-typechain-ethers/contracts/TestContracts.sol b/test/fixture-projects/hardhat-project-typechain-ethers/contracts/TestContracts.sol index 2ac1fa2..a9c730f 100644 --- a/test/fixture-projects/hardhat-project-typechain-ethers/contracts/TestContracts.sol +++ b/test/fixture-projects/hardhat-project-typechain-ethers/contracts/TestContracts.sol @@ -19,4 +19,8 @@ contract PayableReceive { receive() external payable { emit Received(msg.sender, msg.value); } + + function pay() external payable { + emit Received(msg.sender, msg.value); + } } diff --git a/test/integration/deployer/base-contract-interaction.ts b/test/integration/deployer/base-contract-interaction.ts index 2ba6d8a..54fdb91 100644 --- a/test/integration/deployer/base-contract-interaction.ts +++ b/test/integration/deployer/base-contract-interaction.ts @@ -5,6 +5,7 @@ import { useEnvironment } from "../../helpers"; import { ConstructorWithArguments__factory, PayableConstructor__factory, + PayableReceive__factory, } from "../../fixture-projects/hardhat-project-typechain-ethers/typechain-types"; import { Deployer } from "../../../src/deployer/Deployer"; @@ -41,10 +42,28 @@ describe("deployer", () => { expect(await ethersProvider!.provider.getBalance(contract.getAddress())).to.equal(toPay); }); + it("should not deploy contract with invalid constructor arguments", async function () { + const signer = (await deployer.getSigner()) as any; + + await expect(deployer.deploy(ConstructorWithArguments__factory, [signer], {})).to.be.rejectedWith( + `Deployer.deploy(): MinimalContract.deploy(): MinimalContract._createDeployTransaction(): invalid BigNumberish value (argument="value", value="", code=INVALID_ARGUMENT, version=6.10.0)`, + ); + }); + it("should revert if artifact is not a contract", async function () { await expect(deployer.deploy({} as any, [], {})).to.be.rejectedWith( "Deployer.deploy(): Unknown Contract Factory Type", ); }); + + it("should be able to customize overrides for function calls", async function () { + const contract = await deployer.deploy(PayableReceive__factory); + + const toPay = 100n; + + await contract.pay({ value: toPay.toString() }); + + expect(await ethersProvider!.provider.getBalance(contract.getAddress())).to.equal(toPay); + }); }); });