-
Notifications
You must be signed in to change notification settings - Fork 21
/
VestedERC20Factory.sol
78 lines (65 loc) · 2.98 KB
/
VestedERC20Factory.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.11;
import {ERC20} from "./lib/ERC20.sol";
import {VestedERC20} from "./VestedERC20.sol";
import {ClonesWithCallData} from "./lib/ClonesWithCallData.sol";
/// @title VestedERC20Factory
/// @author zefram.eth
/// @notice Factory for deploying VestedERC20 contracts cheaply
contract VestedERC20Factory {
/// -----------------------------------------------------------------------
/// Library usage
/// -----------------------------------------------------------------------
using ClonesWithCallData for address;
/// -----------------------------------------------------------------------
/// Errors
/// -----------------------------------------------------------------------
error Error_InvalidTimeRange();
/// -----------------------------------------------------------------------
/// Events
/// -----------------------------------------------------------------------
event CreateVestedERC20(VestedERC20 vestedERC20);
/// -----------------------------------------------------------------------
/// Immutable parameters
/// -----------------------------------------------------------------------
/// @notice The VestedERC20 used as the template for all clones created
VestedERC20 public immutable implementation;
constructor(VestedERC20 implementation_) {
implementation = implementation_;
}
/// @notice Creates a VestedERC20 contract
/// @dev Uses a modified minimal proxy contract that stores immutable parameters in code and
/// passes them in through calldata. See ClonesWithCallData.
/// @param name The name of the VestedERC20 token
/// @param symbol The symbol of the VestedERC20 token
/// @param decimals The number of decimals used by the VestedERC20 token
/// @param underlying The ERC20 token that is vested
/// @param startTimestamp The start time of the vest, Unix timestamp in seconds
/// @param endTimestamp The end time of the vest, must be greater than startTimestamp, Unix timestamp in seconds
/// @return vestedERC20 The created VestedERC20 contract
function createVestedERC20(
bytes32 name,
bytes32 symbol,
uint8 decimals,
address underlying,
uint64 startTimestamp,
uint64 endTimestamp
) external returns (VestedERC20 vestedERC20) {
if (endTimestamp <= startTimestamp) {
revert Error_InvalidTimeRange();
}
bytes memory ptr = new bytes(101);
assembly {
mstore(add(ptr, 0x20), name)
mstore(add(ptr, 0x40), symbol)
mstore8(add(ptr, 0x60), decimals)
mstore(add(ptr, 0x61), shl(0x60, underlying))
mstore(add(ptr, 0x75), shl(0xc0, startTimestamp))
mstore(add(ptr, 0x7d), shl(0xc0, endTimestamp))
}
vestedERC20 = VestedERC20(
address(implementation).cloneWithCallDataProvision(ptr)
);
emit CreateVestedERC20(vestedERC20);
}
}