/// @title ExampleCloneFactory
/// @notice SPDX-License-Identifier: MIT
/// @author wighawag <https://github.com/wighawag>
/// @author zefram <https://github.com/boredGenius>
/// @author hari <https://github.com/hrkrshnn>
/// @author z0r0z <https://github.com/z0r0z>
/// @author clabby <https://github.com/clabby>
/// @notice Clones with Immutable Args Library
/// @notice Adapted from wighawag (https://github.com/wighawag/clones-with-immutable-args/blob/master/src/ExampleCloneFactory.sol)
#include "./HuffCloneLib.huff"
#define function createClone(address,uint256,uint64,uint8) nonpayable returns (address)
#define function createArrClone(uint256[] calldata) nonpayable returns (address)
#define constant IMPL_SLOT = FREE_STORAGE_POINTER()
/// @notice Creates an `ExampleClone` contract
#define macro CREATE_CLONE() = takes (0) returns (0) {
0x64 calldataload // [uint8]
0x44 calldataload // [uint64, uint8]
0x24 calldataload // [uint256, uint64, uint8]
0x04 calldataload // [address, uint256, uint64, uint8]
// data len = 61 (0x3D)
0x3D 0x40 mstore // [address, uint256, uint64, uint8]
// Store address << 0x60 @ 0x60
0x60 shl // [address << 0x60, uint256, uint64, uint8]
0x60 mstore // [uint256, uint64, uint8]
// Store uint256 @ 0x74
0x74 mstore // [uint64, uint8]
// Store uint64 << 0xC0 @ 0x94
0xC0 shl // [uint64 << 0xC0, uint8]
0x94 mstore // [uint8]
// Store uint8 << 0xF8 @ 0x9C
0xF8 shl // [uint8 << 0xF8]
0x9C mstore // []
0x40 // [data_ptr]
[IMPL_SLOT] sload // [impl_addr, data_ptr]
CLONE(err, 0x00) // [instance]
0x00 mstore // []
0x20 0x00 return
err:
0x00 0x00 revert
}
/// @notice Creates an `ExampleClone` contract that has an immutable
/// uint256 array
#define macro CREATE_ARRAY_CLONE() = takes (0) returns (0) {
0x24 calldataload // [arr_len]
0x05 shl // [arr_len * 0x20]
0x20 add // [arr_len * 0x20 + 0x20]
0x24 // [0x24, arr_len * 0x20 + 0x20]
0x40 // [0x40, 0x24, arr_len * 0x20 + 0x20]
calldatacopy // []
// Set data length in bytes
0x40 dup1 // [0x40, 0x40]
mload // [arr_len, 0x40]
0x05 shl // [arr_len * 0x20, 0x40]
0x40 mstore // [0x40 (data_ptr)]
[IMPL_SLOT] sload // [impl_addr, data_ptr]
CLONE(err, 0x00) // [instance]
0x00 mstore // []
0x20 0x00 return
err:
0x00 0x00 revert
}
#define macro MAIN() = takes (0) returns (0) {
pc calldataload 0xE0 shr
dup1 __FUNC_SIG(createClone) eq clone jumpi
dup1 __FUNC_SIG(createArrClone) eq arr_clone jumpi
clone:
CREATE_CLONE()
arr_clone:
CREATE_ARRAY_CLONE()
}
#define macro CONSTRUCTOR() = takes (0) returns (0) {
0x20 // [size] - byte size to copy
0x20 codesize sub // [offset, size] - offset in the code to copy from
0x00 // [mem, offset, size] - offset in memory to copy to
codecopy // []
0x00 mload
[IMPL_SLOT] // [impl_ptr, impl_addr]
sstore // []
}