diff --git a/src/ClonesWithImmutableArgs.sol b/src/ClonesWithImmutableArgs.sol index 7f00060..c63da30 100644 --- a/src/ClonesWithImmutableArgs.sol +++ b/src/ClonesWithImmutableArgs.sol @@ -419,7 +419,7 @@ library ClonesWithImmutableArgs { // Nonce of the proxy contract (1). mstore8(0x34, 0x01) - deployed := keccak256(0x1e, 0x17) + deployed := and(keccak256(0x1e, 0x17), 0xffffffffffffffffffffffffffffffffffffffff) // If the `call` fails or the code size of `deployed` is zero, revert. // The second argument of the or() call is evaluated first, which is important @@ -480,7 +480,7 @@ library ClonesWithImmutableArgs { // Nonce of the proxy contract (1). mstore8(0x34, 0x01) - deployed := keccak256(0x1e, 0x17) + deployed := and(keccak256(0x1e, 0x17), 0xffffffffffffffffffffffffffffffffffffffff) } } } diff --git a/src/test/ClonesWithImmutableArgs.t.sol b/src/test/ClonesWithImmutableArgs.t.sol new file mode 100644 index 0000000..cc49850 --- /dev/null +++ b/src/test/ClonesWithImmutableArgs.t.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: BSD +pragma solidity ^0.8.4; + +import {DSTest} from "ds-test/test.sol"; + +import {ClonesWithImmutableArgs} from "../ClonesWithImmutableArgs.sol"; +import {ExampleClone} from "../ExampleClone.sol"; + +contract ClonesWithImmutableArgsTest is DSTest { + /// ----------------------------------------------------------------------- + /// Correctness tests + /// ----------------------------------------------------------------------- + function testCorrectness_addressOfClone3CleanAddress(bytes32 salt) public { + uint256 remainderMask = ~(uint256(type(uint160).max)); + address predicted = ClonesWithImmutableArgs.addressOfClone3(salt); + + uint256 remainder; + assembly ("memory-safe") { + remainder := and(predicted, remainderMask) + } + assertEq(remainder, 0); + } + + function testCorrectness_clone3CleanAddress( + address param1, + uint256 param2, + uint64 param3, + uint8 param4, + bytes32 salt + ) public { + address implementation = address(new ExampleClone()); + uint256 remainderMask = ~(uint256(type(uint160).max)); + bytes memory data = abi.encodePacked(param1, param2, param3, param4); + address clone = ClonesWithImmutableArgs.clone3(implementation, data, salt, 0); + + uint256 remainder; + assembly ("memory-safe") { + remainder := and(clone, remainderMask) + } + assertEq(remainder, 0); + } +}