Просмотр исходного кода

Mask computed address in `Create2` and `Clones` libraries (#4941)

Co-authored-by: ernestognw <ernestognw@gmail.com>
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
Xenia 1 год назад
Родитель
Сommit
d398d68944

+ 5 - 0
.changeset/fluffy-steaks-exist.md

@@ -0,0 +1,5 @@
+---
+'openzeppelin-solidity': patch
+---
+
+`Create2`, `Clones`: Mask `computeAddress` and `cloneDeterministic` outputs to produce a clean value for an `address` type (i.e. only use 20 bytes)

+ 1 - 1
contracts/proxy/Clones.sol

@@ -110,7 +110,7 @@ library Clones {
             mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
             mstore(add(ptr, 0x58), salt)
             mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
-            predicted := keccak256(add(ptr, 0x43), 0x55)
+            predicted := and(keccak256(add(ptr, 0x43), 0x55), 0xffffffffffffffffffffffffffffffffffffffff)
         }
     }
 

+ 1 - 1
contracts/utils/Create2.sol

@@ -82,7 +82,7 @@ library Create2 {
             mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
             let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
             mstore8(start, 0xff)
-            addr := keccak256(start, 85)
+            addr := and(keccak256(start, 85), 0xffffffffffffffffffffffffffffffffffffffff)
         }
     }
 }

+ 18 - 0
test/proxy/Clones.t.sol

@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.20;
+
+import {Test} from "forge-std/Test.sol";
+import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
+
+contract ClonesTest is Test {
+    function testPredictDeterministicAddressSpillage(address implementation, bytes32 salt) public {
+        address predicted = Clones.predictDeterministicAddress(implementation, salt);
+        bytes32 spillage;
+        /// @solidity memory-safe-assembly
+        assembly {
+            spillage := and(predicted, 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)
+        }
+        assertEq(spillage, bytes32(0));
+    }
+}

+ 18 - 0
test/utils/Create2.t.sol

@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.20;
+
+import {Test} from "forge-std/Test.sol";
+import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
+
+contract Create2Test is Test {
+    function testComputeAddressSpillage(bytes32 salt, bytes32 bytecodeHash, address deployer) public {
+        address predicted = Create2.computeAddress(salt, bytecodeHash, deployer);
+        bytes32 spillage;
+        /// @solidity memory-safe-assembly
+        assembly {
+            spillage := and(predicted, 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)
+        }
+        assertEq(spillage, bytes32(0));
+    }
+}