Prechádzať zdrojové kódy

Add a Calldata library with `emptyBytes` and `emptyString` functions (#5422)

Co-authored-by: Ernesto García <ernestognw@gmail.com>
Hadrien Croubois 9 mesiacov pred
rodič
commit
352ab13687

+ 5 - 0
.changeset/good-cameras-serve.md

@@ -0,0 +1,5 @@
+---
+"openzeppelin-solidity": minor
+---
+
+`Calldata`: Library with `emptyBytes` and `emptyString` functions to generate empty `bytes` and `string` calldata types.

+ 3 - 10
contracts/account/utils/draft-ERC4337Utils.sol

@@ -5,6 +5,7 @@ pragma solidity ^0.8.20;
 
 import {PackedUserOperation} from "../../interfaces/draft-IERC4337.sol";
 import {Math} from "../../utils/math/Math.sol";
+import {Calldata} from "../../utils/Calldata.sol";
 import {Packing} from "../../utils/Packing.sol";
 
 /**
@@ -107,7 +108,7 @@ library ERC4337Utils {
 
     /// @dev Returns `factoryData` from the {PackedUserOperation}, or empty bytes if the initCode is empty or not properly formatted.
     function factoryData(PackedUserOperation calldata self) internal pure returns (bytes calldata) {
-        return self.initCode.length < 20 ? _emptyCalldataBytes() : self.initCode[20:];
+        return self.initCode.length < 20 ? Calldata.emptyBytes() : self.initCode[20:];
     }
 
     /// @dev Returns `verificationGasLimit` from the {PackedUserOperation}.
@@ -157,14 +158,6 @@ library ERC4337Utils {
 
     /// @dev Returns the fourth section of `paymasterAndData` from the {PackedUserOperation}.
     function paymasterData(PackedUserOperation calldata self) internal pure returns (bytes calldata) {
-        return self.paymasterAndData.length < 52 ? _emptyCalldataBytes() : self.paymasterAndData[52:];
-    }
-
-    // slither-disable-next-line write-after-write
-    function _emptyCalldataBytes() private pure returns (bytes calldata result) {
-        assembly ("memory-safe") {
-            result.offset := 0
-            result.length := 0
-        }
+        return self.paymasterAndData.length < 52 ? Calldata.emptyBytes() : self.paymasterAndData[52:];
     }
 }

+ 24 - 0
contracts/utils/Calldata.sol

@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.20;
+
+/**
+ * @dev Helper library for manipulating objects in calldata.
+ */
+library Calldata {
+    // slither-disable-next-line write-after-write
+    function emptyBytes() internal pure returns (bytes calldata result) {
+        assembly ("memory-safe") {
+            result.offset := 0
+            result.length := 0
+        }
+    }
+
+    // slither-disable-next-line write-after-write
+    function emptyString() internal pure returns (string calldata result) {
+        assembly ("memory-safe") {
+            result.offset := 0
+            result.length := 0
+        }
+    }
+}

+ 22 - 0
test/utils/Calldata.test.js

@@ -0,0 +1,22 @@
+const { ethers } = require('hardhat');
+const { expect } = require('chai');
+const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
+
+async function fixture() {
+  const mock = await ethers.deployContract('$Calldata');
+  return { mock };
+}
+
+describe('Calldata utilities', function () {
+  beforeEach(async function () {
+    Object.assign(this, await loadFixture(fixture));
+  });
+
+  it('emptyBytes', async function () {
+    await expect(this.mock.$emptyBytes()).to.eventually.equal('0x');
+  });
+
+  it('emptyString', async function () {
+    await expect(this.mock.$emptyString()).to.eventually.equal('');
+  });
+});