Skip to content

Commit 3988842

Browse files
committed
Bytes params for vesting factory (#135)
* Bytes params for vesting factory * remove `.only` * add test and fix lint * rename `initialization` -> `initArgs`
1 parent d17caee commit 3988842

File tree

3 files changed

+152
-205
lines changed

3 files changed

+152
-205
lines changed

contracts/finance/VestingWalletConfidentialFactory.sol

Lines changed: 26 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,19 @@ import {VestingWalletCliffConfidential} from "./VestingWalletCliffConfidential.s
1616
*/
1717
abstract contract VestingWalletConfidentialFactory {
1818
struct VestingPlan {
19-
address beneficiary;
2019
externalEuint64 encryptedAmount;
21-
uint48 startTimestamp;
22-
uint48 durationSeconds;
23-
uint48 cliffSeconds;
20+
bytes initArgs;
2421
}
2522

2623
address private immutable _vestingImplementation;
2724

2825
event VestingWalletConfidentialFunded(
2926
address indexed vestingWalletConfidential,
30-
address indexed beneficiary,
3127
address indexed confidentialFungibleToken,
32-
euint64 encryptedAmount,
33-
uint48 startTimestamp,
34-
uint48 durationSeconds,
35-
uint48 cliffSeconds,
36-
address executor
37-
);
38-
event VestingWalletConfidentialCreated(
39-
address indexed vestingWalletConfidential,
40-
address indexed beneficiary,
41-
uint48 startTimestamp,
42-
uint48 durationSeconds,
43-
uint48 cliffSeconds,
44-
address indexed executor
28+
euint64 transferredAmount,
29+
bytes initArgs
4530
);
31+
event VestingWalletConfidentialCreated(address indexed vestingWalletConfidential, bytes initArgs);
4632

4733
constructor() {
4834
_vestingImplementation = _deployVestingWalletImplementation();
@@ -59,50 +45,28 @@ abstract contract VestingWalletConfidentialFactory {
5945
function batchFundVestingWalletConfidential(
6046
address confidentialFungibleToken,
6147
VestingPlan[] calldata vestingPlans,
62-
address executor,
6348
bytes calldata inputProof
6449
) public virtual {
6550
uint256 vestingPlansLength = vestingPlans.length;
6651
for (uint256 i = 0; i < vestingPlansLength; i++) {
6752
VestingPlan memory vestingPlan = vestingPlans[i];
68-
require(
69-
vestingPlan.cliffSeconds <= vestingPlan.durationSeconds,
70-
VestingWalletCliffConfidential.VestingWalletCliffConfidentialInvalidCliffDuration(
71-
vestingPlan.cliffSeconds,
72-
vestingPlan.durationSeconds
73-
)
74-
);
53+
_validateVestingWalletInitArgs(vestingPlan.initArgs);
7554

76-
require(vestingPlan.beneficiary != address(0), OwnableUpgradeable.OwnableInvalidOwner(address(0)));
77-
address vestingWalletAddress = predictVestingWalletConfidential(
78-
vestingPlan.beneficiary,
79-
vestingPlan.startTimestamp,
80-
vestingPlan.durationSeconds,
81-
vestingPlan.cliffSeconds,
82-
executor
83-
);
55+
address vestingWalletAddress = predictVestingWalletConfidential(vestingPlan.initArgs);
8456

85-
euint64 transferredAmount;
86-
{
87-
// avoiding stack too deep with scope
88-
euint64 encryptedAmount = FHE.fromExternal(vestingPlan.encryptedAmount, inputProof);
89-
FHE.allowTransient(encryptedAmount, confidentialFungibleToken);
90-
transferredAmount = IConfidentialFungibleToken(confidentialFungibleToken).confidentialTransferFrom(
91-
msg.sender,
92-
vestingWalletAddress,
93-
encryptedAmount
94-
);
95-
}
57+
euint64 encryptedAmount = FHE.fromExternal(vestingPlan.encryptedAmount, inputProof);
58+
FHE.allowTransient(encryptedAmount, confidentialFungibleToken);
59+
euint64 transferredAmount = IConfidentialFungibleToken(confidentialFungibleToken).confidentialTransferFrom(
60+
msg.sender,
61+
vestingWalletAddress,
62+
encryptedAmount
63+
);
9664

9765
emit VestingWalletConfidentialFunded(
9866
vestingWalletAddress,
99-
vestingPlan.beneficiary,
10067
confidentialFungibleToken,
10168
transferredAmount,
102-
vestingPlan.startTimestamp,
103-
vestingPlan.durationSeconds,
104-
vestingPlan.cliffSeconds,
105-
executor
69+
vestingPlan.initArgs
10670
);
10771
}
10872
}
@@ -112,75 +76,33 @@ abstract contract VestingWalletConfidentialFactory {
11276
*
11377
* Emits a {VestingWalletConfidentialCreated}.
11478
*/
115-
function createVestingWalletConfidential(
116-
address beneficiary,
117-
uint48 startTimestamp,
118-
uint48 durationSeconds,
119-
uint48 cliffSeconds,
120-
address executor
121-
) public virtual returns (address) {
79+
function createVestingWalletConfidential(bytes calldata initArgs) public virtual returns (address) {
12280
// Will revert if clone already created
12381
address vestingWalletConfidentialAddress = Clones.cloneDeterministic(
12482
_vestingImplementation,
125-
_getCreate2VestingWalletConfidentialSalt(
126-
beneficiary,
127-
startTimestamp,
128-
durationSeconds,
129-
cliffSeconds,
130-
executor
131-
)
132-
);
133-
_initializeVestingWallet(
134-
vestingWalletConfidentialAddress,
135-
beneficiary,
136-
startTimestamp,
137-
durationSeconds,
138-
cliffSeconds,
139-
executor
140-
);
141-
emit VestingWalletConfidentialCreated(
142-
vestingWalletConfidentialAddress,
143-
beneficiary,
144-
startTimestamp,
145-
durationSeconds,
146-
cliffSeconds,
147-
executor
83+
_getCreate2VestingWalletConfidentialSalt(initArgs)
14884
);
85+
_initializeVestingWallet(vestingWalletConfidentialAddress, initArgs);
86+
emit VestingWalletConfidentialCreated(vestingWalletConfidentialAddress, initArgs);
14987
return vestingWalletConfidentialAddress;
15088
}
15189

15290
/**
15391
* @dev Predicts the deterministic address for a confidential vesting wallet.
15492
*/
155-
function predictVestingWalletConfidential(
156-
address beneficiary,
157-
uint48 startTimestamp,
158-
uint48 durationSeconds,
159-
uint48 cliffSeconds,
160-
address executor
161-
) public view virtual returns (address) {
93+
function predictVestingWalletConfidential(bytes memory initArgs) public view virtual returns (address) {
16294
return
16395
Clones.predictDeterministicAddress(
16496
_vestingImplementation,
165-
_getCreate2VestingWalletConfidentialSalt(
166-
beneficiary,
167-
startTimestamp,
168-
durationSeconds,
169-
cliffSeconds,
170-
executor
171-
)
97+
_getCreate2VestingWalletConfidentialSalt(initArgs)
17298
);
17399
}
174100

101+
/// @dev Virtual function that must be implemented to validate the initArgs bytes.
102+
function _validateVestingWalletInitArgs(bytes memory initArgs) internal virtual;
103+
175104
/// @dev Virtual function that must be implemented to initialize the vesting wallet at `vestingWalletAddress`.
176-
function _initializeVestingWallet(
177-
address vestingWalletAddress,
178-
address beneficiary,
179-
uint48 startTimestamp,
180-
uint48 durationSeconds,
181-
uint48 cliffSeconds,
182-
address executor
183-
) internal virtual;
105+
function _initializeVestingWallet(address vestingWalletAddress, bytes calldata initArgs) internal virtual;
184106

185107
/**
186108
* @dev Internal function that is called once to deploy the vesting wallet implementation.
@@ -192,13 +114,7 @@ abstract contract VestingWalletConfidentialFactory {
192114
/**
193115
* @dev Gets create2 salt for a confidential vesting wallet.
194116
*/
195-
function _getCreate2VestingWalletConfidentialSalt(
196-
address beneficiary,
197-
uint48 startTimestamp,
198-
uint48 durationSeconds,
199-
uint48 cliffSeconds,
200-
address executor
201-
) internal pure virtual returns (bytes32) {
202-
return keccak256(abi.encodePacked(beneficiary, startTimestamp, durationSeconds, cliffSeconds, executor));
117+
function _getCreate2VestingWalletConfidentialSalt(bytes memory initArgs) internal pure virtual returns (bytes32) {
118+
return keccak256(initArgs);
203119
}
204120
}

contracts/mocks/finance/VestingWalletConfidentialFactoryMock.sol

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,29 @@ abstract contract VestingWalletConfidentialFactoryMock is VestingWalletConfident
1212
return address(new VestingWalletCliffExecutorConfidential());
1313
}
1414

15-
function _initializeVestingWallet(
16-
address vestingWalletAddress,
17-
address beneficiary,
18-
uint48 startTimestamp,
19-
uint48 durationSeconds,
20-
uint48 cliffSeconds,
21-
address executor
22-
) internal virtual override {
15+
function _validateVestingWalletInitArgs(bytes memory initArgs) internal virtual override {
16+
// solhint-disable no-unused-vars
17+
(
18+
address beneficiary,
19+
uint48 startTimestamp,
20+
uint48 durationSeconds,
21+
uint48 cliffSeconds,
22+
address executor
23+
) = abi.decode(initArgs, (address, uint48, uint48, uint48, address));
24+
25+
require(cliffSeconds <= durationSeconds);
26+
require(beneficiary != address(0));
27+
}
28+
29+
function _initializeVestingWallet(address vestingWalletAddress, bytes calldata initArgs) internal virtual override {
30+
(
31+
address beneficiary,
32+
uint48 startTimestamp,
33+
uint48 durationSeconds,
34+
uint48 cliffSeconds,
35+
address executor
36+
) = abi.decode(initArgs, (address, uint48, uint48, uint48, address));
37+
2338
VestingWalletCliffExecutorConfidential(vestingWalletAddress).initialize(
2439
beneficiary,
2540
startTimestamp,

0 commit comments

Comments
 (0)