@@ -2,62 +2,126 @@ import { shouldBehaveLikeVestingConfidential } from './VestingWalletConfidential
22import { FhevmType } from '@fhevm/hardhat-plugin' ;
33import { time } from '@nomicfoundation/hardhat-network-helpers' ;
44import { expect } from 'chai' ;
5+ import { EventLog } from 'ethers' ;
56import { ethers , fhevm } from 'hardhat' ;
67
78const name = 'ConfidentialFungibleToken' ;
89const symbol = 'CFT' ;
910const uri = 'https://example.com/metadata' ;
1011
11- describe ( 'VestingWalletCliffConfidential' , function ( ) {
12- beforeEach ( async function ( ) {
13- const accounts = ( await ethers . getSigners ( ) ) . slice ( 3 ) ;
14- const [ holder , recipient , operator ] = accounts ;
15-
16- const token = await ethers . deployContract ( '$ConfidentialFungibleTokenMock' , [ name , symbol , uri ] ) ;
17-
18- const encryptedInput = await fhevm
19- . createEncryptedInput ( await token . getAddress ( ) , holder . address )
20- . add64 ( 1000 )
21- . encrypt ( ) ;
22-
23- const currentTime = await time . latest ( ) ;
24- const schedule = [ currentTime + 60 , currentTime + 60 * 121 ] ;
25- const vesting = await ethers . deployContract ( '$VestingWalletCliffConfidentialMock' , [
26- operator ,
27- recipient ,
28- currentTime + 60 ,
29- 60 * 60 * 2 /* 2 hours */ ,
30- 60 * 60 /* 1 hour */ ,
31- ] ) ;
32-
33- await ( token as any )
34- . connect ( holder )
35- [ '$_mint(address,bytes32,bytes)' ] ( vesting . target , encryptedInput . handles [ 0 ] , encryptedInput . inputProof ) ;
36-
37- Object . assign ( this , { accounts, holder, recipient, operator, token, vesting, schedule, vestingAmount : 1000 } ) ;
38- } ) ;
12+ for ( const useInitializable of [ false , true ] ) {
13+ describe ( `VestingWalletCliffConfidential${ useInitializable ? 'Initializable' : '' } ` , function ( ) {
14+ beforeEach ( async function ( ) {
15+ const accounts = ( await ethers . getSigners ( ) ) . slice ( 3 ) ;
16+ const [ holder , recipient , operator ] = accounts ;
3917
40- it ( 'should release nothing before cliff' , async function ( ) {
41- await time . increaseTo ( this . schedule [ 0 ] + 60 ) ;
42- await this . vesting . release ( this . token ) ;
18+ const token = await ethers . deployContract ( '$ConfidentialFungibleTokenMock' , [ name , symbol , uri ] ) ;
4319
44- const balanceOfHandle = await this . token . balanceOf ( this . recipient ) ;
45- await expect (
46- fhevm . userDecryptEuint ( FhevmType . euint64 , balanceOfHandle , this . token . target , this . recipient ) ,
47- ) . to . eventually . equal ( 0 ) ;
48- } ) ;
20+ const encryptedInput = await fhevm
21+ . createEncryptedInput ( await token . getAddress ( ) , holder . address )
22+ . add64 ( 1000 )
23+ . encrypt ( ) ;
4924
50- it ( 'should fail construction if cliff is longer than duration' , async function ( ) {
51- await expect (
52- ethers . deployContract ( '$VestingWalletCliffConfidentialMock' , [
53- this . operator ,
54- this . recipient ,
55- ( await time . latest ( ) ) + 60 ,
56- 60 * 10 ,
57- 60 * 60 ,
58- ] ) ,
59- ) . to . be . revertedWithCustomError ( this . vesting , 'InvalidCliffDuration' ) ;
60- } ) ;
25+ const currentTime = await time . latest ( ) ;
26+ const schedule = [ currentTime + 60 , currentTime + 60 * 121 ] ;
27+
28+ let vesting ;
29+ let factory ;
30+ let impl ;
31+
32+ if ( ! useInitializable ) {
33+ vesting = await ethers . deployContract ( '$VestingWalletCliffConfidentialMock' , [
34+ operator ,
35+ recipient ,
36+ currentTime + 60 ,
37+ 60 * 60 * 2 /* 2 hours */ ,
38+ 60 * 60 /* 1 hour */ ,
39+ ] ) ;
40+ } else {
41+ impl = await ethers . deployContract ( '$VestingWalletCliffConfidentialInitializableMock' ) ;
42+ factory = await ethers . deployContract ( 'Create2Factory' ) ;
43+
44+ const callData = await impl . initialize . populateTransaction (
45+ operator ,
46+ recipient ,
47+ currentTime + 60 ,
48+ 60 * 60 * 2 /* 2 hours */ ,
49+ 60 * 60 /* 1 hour */ ,
50+ ) ;
51+ const cloneTx = ( await ( await factory . create2 ( impl . target , callData . data ) ) . wait ( ) ) ! ;
52+ const cloneAddress = ( cloneTx . logs [ 2 ] as EventLog ) . args [ 0 ] ;
53+
54+ vesting = await ethers . getContractAt ( '$VestingWalletCliffConfidentialInitializableMock' , cloneAddress ) ;
55+ }
6156
62- shouldBehaveLikeVestingConfidential ( ) ;
63- } ) ;
57+ await ( token as any )
58+ . connect ( holder )
59+ [ '$_mint(address,bytes32,bytes)' ] ( vesting . target , encryptedInput . handles [ 0 ] , encryptedInput . inputProof ) ;
60+
61+ Object . assign ( this , {
62+ accounts,
63+ holder,
64+ recipient,
65+ operator,
66+ token,
67+ vesting,
68+ schedule,
69+ vestingAmount : 1000 ,
70+ factory,
71+ impl,
72+ } ) ;
73+ } ) ;
74+
75+ it ( 'should release nothing before cliff' , async function ( ) {
76+ await time . increaseTo ( this . schedule [ 0 ] + 60 ) ;
77+ await this . vesting . release ( this . token ) ;
78+
79+ const balanceOfHandle = await this . token . balanceOf ( this . recipient ) ;
80+ await expect (
81+ fhevm . userDecryptEuint ( FhevmType . euint64 , balanceOfHandle , this . token . target , this . recipient ) ,
82+ ) . to . eventually . equal ( 0 ) ;
83+ } ) ;
84+
85+ it ( 'should fail construction if cliff is longer than duration' , async function ( ) {
86+ if ( ! useInitializable ) {
87+ await expect (
88+ ethers . deployContract ( '$VestingWalletCliffConfidentialMock' , [
89+ this . operator ,
90+ this . recipient ,
91+ ( await time . latest ( ) ) + 60 ,
92+ 60 * 10 ,
93+ 60 * 60 ,
94+ ] ) ,
95+ ) . to . be . revertedWithCustomError ( this . vesting , 'InvalidCliffDuration' ) ;
96+ } else {
97+ const callData = await this . impl . initialize . populateTransaction (
98+ this . operator ,
99+ this . recipient ,
100+ ( await time . latest ( ) ) + 60 ,
101+ 60 * 10 ,
102+ 60 * 60 ,
103+ ) ;
104+ await expect ( this . factory . create2 ( this . impl . target , callData . data ) ) . to . be . revertedWithCustomError (
105+ this . vesting ,
106+ 'InvalidCliffDuration' ,
107+ ) ;
108+ }
109+ } ) ;
110+
111+ if ( useInitializable ) {
112+ it ( 'cannot reinitialize' , async function ( ) {
113+ await expect (
114+ this . vesting . initialize (
115+ this . operator ,
116+ this . recipient ,
117+ ( await time . latest ( ) ) + 60 ,
118+ 60 * 60 * 2 /* 2 hours */ ,
119+ 60 * 60 /* 1 hour */ ,
120+ ) ,
121+ ) . to . be . revertedWithCustomError ( this . vesting , 'InvalidInitialization' ) ;
122+ } ) ;
123+ }
124+
125+ shouldBehaveLikeVestingConfidential ( ) ;
126+ } ) ;
127+ }
0 commit comments