Clones.sol 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.2.0) (proxy/Clones.sol)
  3. pragma solidity ^0.8.20;
  4. import {Create2} from "../utils/Create2.sol";
  5. import {Errors} from "../utils/Errors.sol";
  6. /**
  7. * @dev https://eips.ethereum.org/EIPS/eip-1167[ERC-1167] is a standard for
  8. * deploying minimal proxy contracts, also known as "clones".
  9. *
  10. * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
  11. * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
  12. *
  13. * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
  14. * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
  15. * deterministic method.
  16. */
  17. library Clones {
  18. error CloneArgumentsTooLong();
  19. /**
  20. * @dev Deploys and returns the address of a clone that mimics the behavior of `implementation`.
  21. *
  22. * This function uses the create opcode, which should never revert.
  23. */
  24. function clone(address implementation) internal returns (address instance) {
  25. return clone(implementation, 0);
  26. }
  27. /**
  28. * @dev Same as {xref-Clones-clone-address-}[clone], but with a `value` parameter to send native currency
  29. * to the new contract.
  30. *
  31. * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
  32. * to always have enough balance for new deployments. Consider exposing this function under a payable method.
  33. */
  34. function clone(address implementation, uint256 value) internal returns (address instance) {
  35. if (address(this).balance < value) {
  36. revert Errors.InsufficientBalance(address(this).balance, value);
  37. }
  38. assembly ("memory-safe") {
  39. // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
  40. // of the `implementation` address with the bytecode before the address.
  41. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
  42. // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
  43. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
  44. instance := create(value, 0x09, 0x37)
  45. }
  46. if (instance == address(0)) {
  47. revert Errors.FailedDeployment();
  48. }
  49. }
  50. /**
  51. * @dev Deploys and returns the address of a clone that mimics the behavior of `implementation`.
  52. *
  53. * This function uses the create2 opcode and a `salt` to deterministically deploy
  54. * the clone. Using the same `implementation` and `salt` multiple times will revert, since
  55. * the clones cannot be deployed twice at the same address.
  56. */
  57. function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
  58. return cloneDeterministic(implementation, salt, 0);
  59. }
  60. /**
  61. * @dev Same as {xref-Clones-cloneDeterministic-address-bytes32-}[cloneDeterministic], but with
  62. * a `value` parameter to send native currency to the new contract.
  63. *
  64. * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
  65. * to always have enough balance for new deployments. Consider exposing this function under a payable method.
  66. */
  67. function cloneDeterministic(
  68. address implementation,
  69. bytes32 salt,
  70. uint256 value
  71. ) internal returns (address instance) {
  72. if (address(this).balance < value) {
  73. revert Errors.InsufficientBalance(address(this).balance, value);
  74. }
  75. assembly ("memory-safe") {
  76. // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
  77. // of the `implementation` address with the bytecode before the address.
  78. mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
  79. // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
  80. mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
  81. instance := create2(value, 0x09, 0x37, salt)
  82. }
  83. if (instance == address(0)) {
  84. revert Errors.FailedDeployment();
  85. }
  86. }
  87. /**
  88. * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
  89. */
  90. function predictDeterministicAddress(
  91. address implementation,
  92. bytes32 salt,
  93. address deployer
  94. ) internal pure returns (address predicted) {
  95. assembly ("memory-safe") {
  96. let ptr := mload(0x40)
  97. mstore(add(ptr, 0x38), deployer)
  98. mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
  99. mstore(add(ptr, 0x14), implementation)
  100. mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
  101. mstore(add(ptr, 0x58), salt)
  102. mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
  103. predicted := and(keccak256(add(ptr, 0x43), 0x55), 0xffffffffffffffffffffffffffffffffffffffff)
  104. }
  105. }
  106. /**
  107. * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
  108. */
  109. function predictDeterministicAddress(
  110. address implementation,
  111. bytes32 salt
  112. ) internal view returns (address predicted) {
  113. return predictDeterministicAddress(implementation, salt, address(this));
  114. }
  115. /**
  116. * @dev Deploys and returns the address of a clone that mimics the behavior of `implementation` with custom
  117. * immutable arguments. These are provided through `args` and cannot be changed after deployment. To
  118. * access the arguments within the implementation, use {fetchCloneArgs}.
  119. *
  120. * This function uses the create opcode, which should never revert.
  121. */
  122. function cloneWithImmutableArgs(address implementation, bytes memory args) internal returns (address instance) {
  123. return cloneWithImmutableArgs(implementation, args, 0);
  124. }
  125. /**
  126. * @dev Same as {xref-Clones-cloneWithImmutableArgs-address-bytes-}[cloneWithImmutableArgs], but with a `value`
  127. * parameter to send native currency to the new contract.
  128. *
  129. * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
  130. * to always have enough balance for new deployments. Consider exposing this function under a payable method.
  131. */
  132. function cloneWithImmutableArgs(
  133. address implementation,
  134. bytes memory args,
  135. uint256 value
  136. ) internal returns (address instance) {
  137. if (address(this).balance < value) {
  138. revert Errors.InsufficientBalance(address(this).balance, value);
  139. }
  140. bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
  141. assembly ("memory-safe") {
  142. instance := create(value, add(bytecode, 0x20), mload(bytecode))
  143. }
  144. if (instance == address(0)) {
  145. revert Errors.FailedDeployment();
  146. }
  147. }
  148. /**
  149. * @dev Deploys and returns the address of a clone that mimics the behavior of `implementation` with custom
  150. * immutable arguments. These are provided through `args` and cannot be changed after deployment. To
  151. * access the arguments within the implementation, use {fetchCloneArgs}.
  152. *
  153. * This function uses the create2 opcode and a `salt` to deterministically deploy the clone. Using the same
  154. * `implementation`, `args` and `salt` multiple times will revert, since the clones cannot be deployed twice
  155. * at the same address.
  156. */
  157. function cloneDeterministicWithImmutableArgs(
  158. address implementation,
  159. bytes memory args,
  160. bytes32 salt
  161. ) internal returns (address instance) {
  162. return cloneDeterministicWithImmutableArgs(implementation, args, salt, 0);
  163. }
  164. /**
  165. * @dev Same as {xref-Clones-cloneDeterministicWithImmutableArgs-address-bytes-bytes32-}[cloneDeterministicWithImmutableArgs],
  166. * but with a `value` parameter to send native currency to the new contract.
  167. *
  168. * NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
  169. * to always have enough balance for new deployments. Consider exposing this function under a payable method.
  170. */
  171. function cloneDeterministicWithImmutableArgs(
  172. address implementation,
  173. bytes memory args,
  174. bytes32 salt,
  175. uint256 value
  176. ) internal returns (address instance) {
  177. bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
  178. return Create2.deploy(value, salt, bytecode);
  179. }
  180. /**
  181. * @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.
  182. */
  183. function predictDeterministicAddressWithImmutableArgs(
  184. address implementation,
  185. bytes memory args,
  186. bytes32 salt,
  187. address deployer
  188. ) internal pure returns (address predicted) {
  189. bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
  190. return Create2.computeAddress(salt, keccak256(bytecode), deployer);
  191. }
  192. /**
  193. * @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.
  194. */
  195. function predictDeterministicAddressWithImmutableArgs(
  196. address implementation,
  197. bytes memory args,
  198. bytes32 salt
  199. ) internal view returns (address predicted) {
  200. return predictDeterministicAddressWithImmutableArgs(implementation, args, salt, address(this));
  201. }
  202. /**
  203. * @dev Get the immutable args attached to a clone.
  204. *
  205. * - If `instance` is a clone that was deployed using `clone` or `cloneDeterministic`, this
  206. * function will return an empty array.
  207. * - If `instance` is a clone that was deployed using `cloneWithImmutableArgs` or
  208. * `cloneDeterministicWithImmutableArgs`, this function will return the args array used at
  209. * creation.
  210. * - If `instance` is NOT a clone deployed using this library, the behavior is undefined. This
  211. * function should only be used to check addresses that are known to be clones.
  212. */
  213. function fetchCloneArgs(address instance) internal view returns (bytes memory) {
  214. bytes memory result = new bytes(instance.code.length - 45); // revert if length is too short
  215. assembly ("memory-safe") {
  216. extcodecopy(instance, add(result, 32), 45, mload(result))
  217. }
  218. return result;
  219. }
  220. /**
  221. * @dev Helper that prepares the initcode of the proxy with immutable args.
  222. *
  223. * An assembly variant of this function requires copying the `args` array, which can be efficiently done using
  224. * `mcopy`. Unfortunately, that opcode is not available before cancun. A pure solidity implementation using
  225. * abi.encodePacked is more expensive but also more portable and easier to review.
  226. *
  227. * NOTE: https://eips.ethereum.org/EIPS/eip-170[EIP-170] limits the length of the contract code to 24576 bytes.
  228. * With the proxy code taking 45 bytes, that limits the length of the immutable args to 24531 bytes.
  229. */
  230. function _cloneCodeWithImmutableArgs(
  231. address implementation,
  232. bytes memory args
  233. ) private pure returns (bytes memory) {
  234. if (args.length > 24531) revert CloneArgumentsTooLong();
  235. return
  236. abi.encodePacked(
  237. hex"61",
  238. uint16(args.length + 45),
  239. hex"3d81600a3d39f3363d3d373d3d3d363d73",
  240. implementation,
  241. hex"5af43d82803e903d91602b57fd5bf3",
  242. args
  243. );
  244. }
  245. }