From 28dd490726f045f7137fa1903b7a6b8a52d6ffcb Mon Sep 17 00:00:00 2001 From: Philippe Dumonet Date: Sat, 9 Apr 2022 00:27:11 +0200 Subject: [PATCH] Optimize ERC1167 proxy creation code by 1 opcode (#3329) --- CHANGELOG.md | 1 + contracts/proxy/Clones.sol | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae7826d50..b483f71fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased * `ERC2981`: make `royaltiInfo` public to allow super call in overrides. ([#3305](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3305)) + * `Clones`: optimize clone creation ([#3329](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3329)) * `TimelockController`: Migrate `_call` to `_execute` and allow inheritance and overriding similar to `Governor`. ([#3317](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3317)) ## Unreleased diff --git a/contracts/proxy/Clones.sol b/contracts/proxy/Clones.sol index 31ece8f81..81c956c80 100644 --- a/contracts/proxy/Clones.sol +++ b/contracts/proxy/Clones.sol @@ -25,10 +25,10 @@ library Clones { function clone(address implementation) internal returns (address instance) { assembly { let ptr := mload(0x40) - mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) - mstore(add(ptr, 0x14), shl(0x60, implementation)) - mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) - instance := create(0, ptr, 0x37) + mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d7300000000000000000000000000) + mstore(add(ptr, 0x13), shl(0x60, implementation)) + mstore(add(ptr, 0x27), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) + instance := create(0, ptr, 0x36) } require(instance != address(0), "ERC1167: create failed"); } @@ -43,10 +43,10 @@ library Clones { function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { assembly { let ptr := mload(0x40) - mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) - mstore(add(ptr, 0x14), shl(0x60, implementation)) - mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) - instance := create2(0, ptr, 0x37, salt) + mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d7300000000000000000000000000) + mstore(add(ptr, 0x13), shl(0x60, implementation)) + mstore(add(ptr, 0x27), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000) + instance := create2(0, ptr, 0x36, salt) } require(instance != address(0), "ERC1167: create2 failed"); } @@ -61,13 +61,13 @@ library Clones { ) internal pure returns (address predicted) { assembly { let ptr := mload(0x40) - mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) - mstore(add(ptr, 0x14), shl(0x60, implementation)) - mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000) - mstore(add(ptr, 0x38), shl(0x60, deployer)) - mstore(add(ptr, 0x4c), salt) - mstore(add(ptr, 0x6c), keccak256(ptr, 0x37)) - predicted := keccak256(add(ptr, 0x37), 0x55) + mstore(ptr, 0x602d8060093d393df3363d3d373d3d3d363d7300000000000000000000000000) + mstore(add(ptr, 0x13), shl(0x60, implementation)) + mstore(add(ptr, 0x27), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000) + mstore(add(ptr, 0x37), shl(0x60, deployer)) + mstore(add(ptr, 0x4b), salt) + mstore(add(ptr, 0x6b), keccak256(ptr, 0x36)) + predicted := keccak256(add(ptr, 0x36), 0x55) } }