Skip to content

Commit af7807c

Browse files
authored
Merge pull request #5199 from fwx5618177/feat/checkConstructorArgsType
feat: check check constructor args type
2 parents 20a89c4 + cb2ad86 commit af7807c

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

.changeset/thick-beers-tie.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@nomicfoundation/hardhat-verify": patch
3+
---
4+
5+
Improved validation of contructor arguments (thanks @fwx5618177!)

packages/hardhat-verify/src/internal/utilities.ts

+19
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919

2020
import { LibraryToAddress } from "./solc/artifacts";
2121
import {
22+
ABIArgumentTypeErrorType,
2223
isABIArgumentLengthError,
2324
isABIArgumentOverflowError,
2425
isABIArgumentTypeError,
@@ -228,6 +229,24 @@ export async function encodeArguments(
228229
const contractInterface = new Interface(abi);
229230
let encodedConstructorArguments;
230231
try {
232+
// encodeDeploy doesn't catch subtle type mismatches, such as a number
233+
// being passed when a string is expected, so we have to validate the
234+
// scenario manually.
235+
const expectedConstructorArgs = contractInterface.deploy.inputs;
236+
constructorArguments.forEach((arg, i) => {
237+
if (
238+
expectedConstructorArgs[i]?.type === "string" &&
239+
typeof arg !== "string"
240+
) {
241+
throw new ABIArgumentTypeError({
242+
code: "INVALID_ARGUMENT",
243+
argument: expectedConstructorArgs[i].name,
244+
value: arg,
245+
reason: "invalid string value",
246+
} as ABIArgumentTypeErrorType);
247+
}
248+
});
249+
231250
encodedConstructorArguments = contractInterface
232251
.encodeDeploy(constructorArguments)
233252
.replace("0x", "");

packages/hardhat-verify/test/unit/utilities.ts

+33
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,39 @@ but 2 arguments were provided instead.`);
537537
);
538538
});
539539

540+
it("should throw if a parameter type does not match its expected type: number instead of string", async () => {
541+
const abi: JsonFragment[] = [
542+
{
543+
inputs: [
544+
{
545+
name: "amount",
546+
type: "uint256",
547+
},
548+
{
549+
name: "amount",
550+
type: "string",
551+
},
552+
{
553+
name: "amount",
554+
type: "address",
555+
},
556+
],
557+
stateMutability: "nonpayable",
558+
type: "constructor",
559+
},
560+
];
561+
const constructorArguments: any[] = [
562+
50,
563+
50, // Invalid string
564+
"0x752C8191E6b1Db38B41A8c8921F7a703F2969d18",
565+
];
566+
await expect(
567+
encodeArguments(abi, sourceName, contractName, constructorArguments)
568+
).to.be.rejectedWith(
569+
/Value 50 cannot be encoded for the parameter amount./
570+
);
571+
});
572+
540573
it("should throw if an unsafe integer is provided as an argument", async () => {
541574
const abi: JsonFragment[] = [
542575
{

0 commit comments

Comments
 (0)