Skip to content

Commit d398d68

Browse files
byshapeernestognwAmxx
authored
Mask computed address in Create2 and Clones libraries (#4941)
Co-authored-by: ernestognw <[email protected]> Co-authored-by: Hadrien Croubois <[email protected]>
1 parent ad27fb6 commit d398d68

File tree

5 files changed

+43
-2
lines changed

5 files changed

+43
-2
lines changed

.changeset/fluffy-steaks-exist.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'openzeppelin-solidity': patch
3+
---
4+
5+
`Create2`, `Clones`: Mask `computeAddress` and `cloneDeterministic` outputs to produce a clean value for an `address` type (i.e. only use 20 bytes)

contracts/proxy/Clones.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ library Clones {
110110
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
111111
mstore(add(ptr, 0x58), salt)
112112
mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
113-
predicted := keccak256(add(ptr, 0x43), 0x55)
113+
predicted := and(keccak256(add(ptr, 0x43), 0x55), 0xffffffffffffffffffffffffffffffffffffffff)
114114
}
115115
}
116116

contracts/utils/Create2.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ library Create2 {
8282
mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
8383
let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
8484
mstore8(start, 0xff)
85-
addr := keccak256(start, 85)
85+
addr := and(keccak256(start, 85), 0xffffffffffffffffffffffffffffffffffffffff)
8686
}
8787
}
8888
}

test/proxy/Clones.t.sol

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.20;
4+
5+
import {Test} from "forge-std/Test.sol";
6+
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
7+
8+
contract ClonesTest is Test {
9+
function testPredictDeterministicAddressSpillage(address implementation, bytes32 salt) public {
10+
address predicted = Clones.predictDeterministicAddress(implementation, salt);
11+
bytes32 spillage;
12+
/// @solidity memory-safe-assembly
13+
assembly {
14+
spillage := and(predicted, 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)
15+
}
16+
assertEq(spillage, bytes32(0));
17+
}
18+
}

test/utils/Create2.t.sol

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.20;
4+
5+
import {Test} from "forge-std/Test.sol";
6+
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
7+
8+
contract Create2Test is Test {
9+
function testComputeAddressSpillage(bytes32 salt, bytes32 bytecodeHash, address deployer) public {
10+
address predicted = Create2.computeAddress(salt, bytecodeHash, deployer);
11+
bytes32 spillage;
12+
/// @solidity memory-safe-assembly
13+
assembly {
14+
spillage := and(predicted, 0xffffffffffffffffffffffff0000000000000000000000000000000000000000)
15+
}
16+
assertEq(spillage, bytes32(0));
17+
}
18+
}

0 commit comments

Comments
 (0)