Skip to content

Commit

Permalink
Merge pull request #3177 from NomicFoundation/relax-eth-storage-at-va…
Browse files Browse the repository at this point in the history
…lidation

Make eth_getStorageAt more permissive
  • Loading branch information
alcuadrado authored Sep 14, 2022
2 parents bbccf5c + 10f03fb commit f7d3843
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-cooks-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hardhat": patch
---

Make `eth_getStorageAt` more permissive
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,37 @@ function validateStorageSlot(u: unknown, c: t.Context): t.Validation<bigint> {
);
}

if (u.match(/^0x(?:[0-9a-fA-F]*)*$/) === null) {
return t.failure(
u,
c,
`Storage slot argument must be a valid hexadecimal prefixed with "0x", got '${u}'`
);
if (u === "") {
return t.failure(u, c, "Storage slot argument cannot be an empty string");
}

if (u.startsWith("0x")) {
if (u.length > 66) {
return t.failure(
u,
c,
`Storage slot argument must have a length of at most 66 ("0x" + 32 bytes), but '${u}' has a length of ${u.length}`
);
}
} else {
if (u.length > 64) {
return t.failure(
u,
c,
`Storage slot argument must have a length of at most 64 (32 bytes), but '${u}' has a length of ${u.length}`
);
}
}

if (u.length !== 66) {
if (u.match(/^(0x)?([0-9a-fA-F]){0,64}$/) === null) {
return t.failure(
u,
c,
`Storage slot argument must have a length of 66 ("0x" + 32 bytes), but '${u}' has a length of ${u.length}`
`Storage slot argument must be a valid hexadecimal, got '${u}'`
);
}

return t.success(BigInt(u));
return t.success(u === "0x" ? 0n : BigInt(u.startsWith("0x") ? u : `0x${u}`));
}

export const rpcAddress = new t.Type<Buffer>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,69 @@ describe("Eth module", function () {
);
});

it("should accept short hex strings", async function () {
const validHexStrings = [
"0x",
"0x0",
"0x00",
"0x000",
"0x1",
"0x01",
"0x001",
"0xA",
"0x0A",
"0x00A",
"0xb",
"0x0b",
"0x00b",
];

for (const storageSlot of validHexStrings) {
assert.strictEqual(
await this.provider.send("eth_getStorageAt", [
"0x0101010101010101010101010101010101010101",
storageSlot,
]),
"0x0000000000000000000000000000000000000000000000000000000000000000"
);
}
});

it("should accept storage slots without the 0x prefix", async function () {
const validHexStrings = [
"0",
"00",
"000",
"1",
"01",
"001",
"A",
"0A",
"00A",
"b",
"0b",
"00b",
];

for (const storageSlot of validHexStrings) {
assert.strictEqual(
await this.provider.send("eth_getStorageAt", [
"0x0101010101010101010101010101010101010101",
storageSlot,
]),
"0x0000000000000000000000000000000000000000000000000000000000000000"
);
}

assert.strictEqual(
await this.provider.send("eth_getStorageAt", [
"0x0101010101010101010101010101010101010101",
"0000000000000000000000000000000000000000000000000000000000000000",
]),
"0x0000000000000000000000000000000000000000000000000000000000000000"
);
});

it("should not accept plain numbers", async function () {
await assertInvalidArgumentsError(
this.provider,
Expand All @@ -272,21 +335,21 @@ describe("Eth module", function () {
);
});

it("should not accept invalid hex strings", async function () {
it("should not accept empty strings", async function () {
await assertInvalidArgumentsError(
this.provider,
"eth_getStorageAt",
["0x0101010101010101010101010101010101010101", "0xABCDEFG"],
"Storage slot argument must be a valid hexadecimal prefixed with \"0x\", got '0xABCDEFG'"
["0x0101010101010101010101010101010101010101", ""],
"Storage slot argument cannot be an empty string"
);
});

it("should not accept hex strings that are too short", async function () {
it("should not accept invalid hex strings", async function () {
await assertInvalidArgumentsError(
this.provider,
"eth_getStorageAt",
["0x0101010101010101010101010101010101010101", "0x0"],
`Storage slot argument must have a length of 66 ("0x" + 32 bytes), but '0x0' has a length of 3`
["0x0101010101010101010101010101010101010101", "0xABCDEFG"],
"Storage slot argument must be a valid hexadecimal, got '0xABCDEFG'"
);
});

Expand All @@ -298,7 +361,17 @@ describe("Eth module", function () {
"0x0101010101010101010101010101010101010101",
"0x00000000000000000000000000000000000000000000000000000000000000000",
],
`Storage slot argument must have a length of 66 ("0x" + 32 bytes), but '0x00000000000000000000000000000000000000000000000000000000000000000' has a length of 67`
`Storage slot argument must have a length of at most 66 ("0x" + 32 bytes), but '0x00000000000000000000000000000000000000000000000000000000000000000' has a length of 67`
);

await assertInvalidArgumentsError(
this.provider,
"eth_getStorageAt",
[
"0x0101010101010101010101010101010101010101",
"00000000000000000000000000000000000000000000000000000000000000000",
],
`Storage slot argument must have a length of at most 64 (32 bytes), but '00000000000000000000000000000000000000000000000000000000000000000' has a length of 65`
);
});
});
Expand Down

0 comments on commit f7d3843

Please sign in to comment.