Skip to content

Commit 8bff7e4

Browse files
vesting factory
1 parent 7539d02 commit 8bff7e4

File tree

2 files changed

+75
-8
lines changed

2 files changed

+75
-8
lines changed

src/EnsoVestingFactory.sol

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// SPDX-License-Identifier: GPL-3.0-only
2+
pragma solidity ^0.8.20;
3+
4+
import { SafeERC20, IERC20 } from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
5+
import { Ownable } from "openzeppelin-contracts/access/Ownable.sol";
6+
import { EnsoVestingWallet } from "./EnsoVestingWallet.sol";
7+
8+
contract EnsoVestingFactory is Ownable {
9+
using SafeERC20 for IERC20;
10+
11+
IERC20 private immutable _token;
12+
13+
struct VestingOptions {
14+
address beneficiary;
15+
uint256 amount;
16+
uint64 startTimestamp;
17+
uint64 durationSeconds;
18+
uint64 cliffSeconds;
19+
}
20+
21+
event VestingWalletCreated(
22+
address wallet,
23+
address beneficiary,
24+
uint256 amount,
25+
uint64 startTimestamp,
26+
uint64 durationSeconds,
27+
uint64 cliffSeconds
28+
);
29+
30+
constructor(address token, address owner) Ownable(owner) {
31+
_token = IERC20(token);
32+
}
33+
34+
function token() external view returns (address) {
35+
return address(_token);
36+
}
37+
38+
function create(VestingOptions calldata options) external onlyOwner {
39+
_create(options);
40+
}
41+
42+
function batchCreate(VestingOptions[] calldata options) external onlyOwner {
43+
for (uint256 i = 0; i < options.length; i++) {
44+
_create(options[i]);
45+
}
46+
}
47+
48+
function _create(VestingOptions calldata options) internal {
49+
EnsoVestingWallet wallet = new EnsoVestingWallet(
50+
_token,
51+
address(this),
52+
options.beneficiary,
53+
options.startTimestamp,
54+
options.durationSeconds,
55+
options.cliffSeconds
56+
);
57+
_token.safeTransferFrom(msg.sender, address(wallet), options.amount);
58+
emit VestingWalletCreated(
59+
address(wallet),
60+
options.beneficiary,
61+
options.amount,
62+
options.startTimestamp,
63+
options.durationSeconds,
64+
options.cliffSeconds
65+
);
66+
}
67+
}

src/EnsoVesting.sol renamed to src/EnsoVestingWallet.sol

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pragma solidity ^0.8.20;
77
import { SafeERC20, IERC20 } from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol";
88
import { Ownable } from "openzeppelin-contracts/access/Ownable.sol";
99

10-
contract EnsoVesting {
10+
contract EnsoVestingWallet is Ownable {
1111
using SafeERC20 for IERC20;
1212

1313
event TokenReleased(uint256 amount);
@@ -28,17 +28,17 @@ contract EnsoVesting {
2828
error NotRevocable();
2929
error NotRevoker(address sender, address revoker);
3030

31-
constructor(address token, address revoker, address beneficiary, uint64 startTimestamp, uint64 durationSeconds, uint64 cliffSeconds) Ownable(beneficiary) {
31+
constructor(IERC20 token, address revoker, address beneficiary, uint64 startTimestamp, uint64 durationSeconds, uint64 cliffSeconds) Ownable(beneficiary) {
3232
if (cliffSeconds > durationSeconds) {
3333
revert InvalidCliffDuration(cliffSeconds, durationSeconds);
3434
}
3535
_start = startTimestamp;
3636
_duration = durationSeconds;
3737
_cliff = startTimestamp + cliffSeconds;
38-
_token = IERC20(token);
38+
_token = token;
3939
if (revoker != address(0)) {
4040
_revoker = revoker;
41-
_revocable = true;
41+
revocable = true;
4242
}
4343
}
4444

@@ -66,21 +66,21 @@ contract EnsoVesting {
6666
/**
6767
* @dev Getter for the cliff timestamp.
6868
*/
69-
function cliff() external view virtual returns (uint256) {
69+
function cliff() public view virtual returns (uint256) {
7070
return _cliff;
7171
}
7272

7373
/**
7474
* @dev Getter for the token address.
7575
*/
76-
function token() external view returns (address) {
76+
function token() public view returns (address) {
7777
return address(_token);
7878
}
7979

8080
/**
8181
* @dev Getter for the revoker address.
8282
*/
83-
function revoker() external view returns (address) {
83+
function revoker() public view returns (address) {
8484
return _revoker;
8585
}
8686

@@ -125,7 +125,7 @@ contract EnsoVesting {
125125
revoked = true;
126126
uint256 amount = _token.balanceOf(address(this));
127127
_token.safeTransfer(receiver, amount);
128-
emit Revoked(amount);
128+
emit VestingRevoked(amount, receiver);
129129
}
130130

131131
/**

0 commit comments

Comments
 (0)