1+ // SPDX-License-Identifier: UNLICENSED
2+ pragma solidity 0.8.28 ;
3+
4+ import {Test, console} from "forge-std/Test.sol " ;
5+
6+ import {VestingParams, IVestingParams} from "src/tokenDistribution/vesting/VestingParams.sol " ;
7+ import {Beneficiary, VestingType, Schedule} from "src/tokenDistribution/utils/Common.sol " ;
8+
9+ contract VestingParamsTest is Test {
10+ VestingParams vestingParams;
11+
12+ address teamBeneficiary1;
13+ address teamBeneficiary2;
14+ address liquidityBeneficiary;
15+
16+ function setUp () external {
17+ (
18+ Beneficiary[] memory teamBeneficiaries ,
19+ Beneficiary[] memory liquidityBeneficiaries
20+ ) = _generateBeneficiaries ();
21+
22+ vestingParams = new VestingParams (teamBeneficiaries, liquidityBeneficiaries);
23+ }
24+
25+ // region - Deploy -
26+
27+ function test_deploy () external {
28+ (
29+ Beneficiary[] memory expectedTeamBeneficiaries ,
30+ Beneficiary[] memory expectedLiquidityBeneficiaries
31+ ) = _generateBeneficiaries ();
32+
33+ Beneficiary[] memory teamBeneficiaries = vestingParams.getBeneficiaries (VestingType.TEAM);
34+
35+ for (uint256 i = 0 ; i < teamBeneficiaries.length ; i++ ) {
36+ assertEq (expectedTeamBeneficiaries[i].account, teamBeneficiaries[i].account);
37+ assertEq (expectedTeamBeneficiaries[i].amount, teamBeneficiaries[i].amount);
38+ }
39+
40+ Beneficiary[] memory liquidityBeneficiaries = vestingParams.getBeneficiaries (VestingType.LIQUIDITY);
41+
42+ for (uint256 i = 0 ; i < liquidityBeneficiaries.length ; i++ ) {
43+ assertEq (expectedLiquidityBeneficiaries[i].account, liquidityBeneficiaries[i].account);
44+ assertEq (expectedLiquidityBeneficiaries[i].amount, liquidityBeneficiaries[i].amount);
45+ }
46+ }
47+
48+ function test_deploy_revertIfZeroTeamBeneficiaries () external {
49+ (
50+ Beneficiary[] memory teamBeneficiaries ,
51+ Beneficiary[] memory liquidityBeneficiaries
52+ ) = _generateBeneficiaries ();
53+
54+ teamBeneficiaries = new Beneficiary [](0 );
55+
56+ vm.expectRevert (IVestingParams.ZeroBeneficiaries.selector );
57+
58+ vestingParams = new VestingParams (teamBeneficiaries, liquidityBeneficiaries);
59+ }
60+
61+ function test_deploy_revertIfZeroLiquidityBeneficiaries () external {
62+ (
63+ Beneficiary[] memory teamBeneficiaries ,
64+ Beneficiary[] memory liquidityBeneficiaries
65+ ) = _generateBeneficiaries ();
66+
67+ liquidityBeneficiaries = new Beneficiary [](0 );
68+
69+ vm.expectRevert (IVestingParams.ZeroBeneficiaries.selector );
70+
71+ vestingParams = new VestingParams (teamBeneficiaries, liquidityBeneficiaries);
72+ }
73+
74+ function test_deploy_revertIfZeroAccount () external {
75+ (
76+ Beneficiary[] memory teamBeneficiaries ,
77+ Beneficiary[] memory liquidityBeneficiaries
78+ ) = _generateBeneficiaries ();
79+
80+ teamBeneficiaries[0 ].account = address (0 );
81+
82+ vm.expectRevert (IVestingParams.ZeroAddress.selector );
83+
84+ vestingParams = new VestingParams (teamBeneficiaries, liquidityBeneficiaries);
85+ }
86+
87+ function test_deploy_revertIfZeroAmount () external {
88+ (
89+ Beneficiary[] memory teamBeneficiaries ,
90+ Beneficiary[] memory liquidityBeneficiaries
91+ ) = _generateBeneficiaries ();
92+
93+ teamBeneficiaries[0 ].amount = 0 ;
94+
95+ vm.expectRevert (IVestingParams.ZeroAmount.selector );
96+
97+ vestingParams = new VestingParams (teamBeneficiaries, liquidityBeneficiaries);
98+ }
99+
100+ function test_deploy_revertIfIncorrectBeneficiaryAmounts (uint256 incorrectAmount ) external {
101+ (
102+ Beneficiary[] memory teamBeneficiaries ,
103+ Beneficiary[] memory liquidityBeneficiaries
104+ ) = _generateBeneficiaries ();
105+
106+ incorrectAmount = bound (incorrectAmount, 1 , type (uint128 ).max);
107+ vm.assume (teamBeneficiaries[0 ].amount != incorrectAmount);
108+
109+ teamBeneficiaries[0 ].amount = incorrectAmount;
110+
111+ vm.expectRevert (IVestingParams.IncorrectBeneficiaryAmounts.selector );
112+
113+ vestingParams = new VestingParams (teamBeneficiaries, liquidityBeneficiaries);
114+ }
115+
116+ // endregion
117+
118+ // region - Get beneficiaries and schedule -
119+
120+ function test_getBeneficiariesAndSchedule () external {
121+ (
122+ Beneficiary[] memory expectedTeamBeneficiaries ,
123+ Beneficiary[] memory expectedLiquidityBeneficiaries
124+ ) = _generateBeneficiaries ();
125+
126+ (Beneficiary[] memory teamBeneficiaries , Schedule memory teamSchedule ) = vestingParams.getBeneficiariesAndSchedule (VestingType.TEAM);
127+
128+ for (uint256 i = 0 ; i < teamBeneficiaries.length ; i++ ) {
129+ assertEq (expectedTeamBeneficiaries[i].account, teamBeneficiaries[i].account);
130+ assertEq (expectedTeamBeneficiaries[i].amount, teamBeneficiaries[i].amount);
131+ }
132+
133+ assertEq (teamSchedule.startTime, block .timestamp );
134+ assertEq (teamSchedule.periods.length , vestingParams.TEAM_TOTAL_PERIODS ());
135+ assertEq (teamSchedule.periods[0 ].portion, vestingParams.TEAM_TGE_PORTION ());
136+ assertEq (teamSchedule.periods[0 ].endTime, block .timestamp );
137+ assertEq (teamSchedule.periods[1 ].portion, 0 );
138+ assertEq (teamSchedule.periods[1 ].endTime, block .timestamp + vestingParams.MONTH ());
139+ assertEq (teamSchedule.periods[13 ].portion, vestingParams.TEAM_VESTING_PORTION ());
140+ assertEq (teamSchedule.periods[13 ].endTime, block .timestamp + 13 * vestingParams.MONTH ());
141+ // ...
142+ assertEq (teamSchedule.periods[37 ].portion, vestingParams.TEAM_VESTING_PORTION ());
143+ assertEq (teamSchedule.periods[37 ].endTime, block .timestamp + 37 * vestingParams.MONTH ());
144+
145+ (Beneficiary[] memory liquidityBeneficiaries , Schedule memory liquiditySchedule ) = vestingParams.getBeneficiariesAndSchedule (VestingType.LIQUIDITY);
146+
147+ for (uint256 i = 0 ; i < liquidityBeneficiaries.length ; i++ ) {
148+ assertEq (expectedLiquidityBeneficiaries[i].account, liquidityBeneficiaries[i].account);
149+ assertEq (expectedLiquidityBeneficiaries[i].amount, liquidityBeneficiaries[i].amount);
150+ }
151+
152+ assertEq (liquiditySchedule.startTime, block .timestamp );
153+ assertEq (liquiditySchedule.periods.length , vestingParams.LIQUIDITY_TOTAL_PERIODS ());
154+ assertEq (liquiditySchedule.periods[0 ].portion, vestingParams.LIQUIDITY_TGE_PORTION ());
155+ assertEq (liquiditySchedule.periods[0 ].endTime, block .timestamp );
156+ assertEq (liquiditySchedule.periods[1 ].portion, 0 );
157+ assertEq (liquiditySchedule.periods[1 ].endTime, block .timestamp + vestingParams.MONTH ());
158+ assertEq (liquiditySchedule.periods[4 ].portion, vestingParams.LIQUIDITY_VESTING_PORTION ());
159+ assertEq (liquiditySchedule.periods[4 ].endTime, block .timestamp + 4 * vestingParams.MONTH ());
160+ // ...
161+ assertEq (liquiditySchedule.periods[23 ].portion, vestingParams.LIQUIDITY_VESTING_PORTION ());
162+ assertEq (liquiditySchedule.periods[23 ].endTime, block .timestamp + 23 * vestingParams.MONTH ());
163+ }
164+
165+ // endregion
166+
167+ // region - Ges schedule -
168+
169+ function test_getSchedule_TEAM () external view {
170+ Schedule memory teamSchedule = vestingParams.getSchedule (VestingType.TEAM);
171+
172+ assertEq (teamSchedule.startTime, block .timestamp );
173+ assertEq (teamSchedule.periods.length , vestingParams.TEAM_TOTAL_PERIODS ());
174+ assertEq (teamSchedule.periods[0 ].portion, vestingParams.TEAM_TGE_PORTION ());
175+ assertEq (teamSchedule.periods[0 ].endTime, block .timestamp );
176+ assertEq (teamSchedule.periods[1 ].portion, 0 );
177+ assertEq (teamSchedule.periods[1 ].endTime, block .timestamp + vestingParams.MONTH ());
178+ assertEq (teamSchedule.periods[13 ].portion, vestingParams.TEAM_VESTING_PORTION ());
179+ assertEq (teamSchedule.periods[13 ].endTime, block .timestamp + 13 * vestingParams.MONTH ());
180+ // ...
181+ assertEq (teamSchedule.periods[37 ].portion, vestingParams.TEAM_VESTING_PORTION ());
182+ assertEq (teamSchedule.periods[37 ].endTime, block .timestamp + 37 * vestingParams.MONTH ());
183+ }
184+
185+ function test_getSchedule_LIQUIDITY () external view {
186+ Schedule memory liquiditySchedule = vestingParams.getSchedule (VestingType.LIQUIDITY);
187+
188+ assertEq (liquiditySchedule.startTime, block .timestamp );
189+ assertEq (liquiditySchedule.periods.length , vestingParams.LIQUIDITY_TOTAL_PERIODS ());
190+ assertEq (liquiditySchedule.periods[0 ].portion, vestingParams.LIQUIDITY_TGE_PORTION ());
191+ assertEq (liquiditySchedule.periods[0 ].endTime, block .timestamp );
192+ assertEq (liquiditySchedule.periods[1 ].portion, 0 );
193+ assertEq (liquiditySchedule.periods[1 ].endTime, block .timestamp + vestingParams.MONTH ());
194+ assertEq (liquiditySchedule.periods[4 ].portion, vestingParams.LIQUIDITY_VESTING_PORTION ());
195+ assertEq (liquiditySchedule.periods[4 ].endTime, block .timestamp + 4 * vestingParams.MONTH ());
196+ // ...
197+ assertEq (liquiditySchedule.periods[23 ].portion, vestingParams.LIQUIDITY_VESTING_PORTION ());
198+ assertEq (liquiditySchedule.periods[23 ].endTime, block .timestamp + 23 * vestingParams.MONTH ());
199+ }
200+
201+ // endregion
202+
203+ // region - Get vesting params -
204+
205+ function test_getVestingParams_TEAM () external view {
206+ (
207+ uint256 totalAmount ,
208+ uint256 totalPeriods ,
209+ uint256 tgePortions ,
210+ uint256 vestingStartMonth ,
211+ uint256 vestingPortion
212+ ) = vestingParams.getVestingParams (VestingType.TEAM);
213+
214+ assertEq (totalAmount, vestingParams.TEAM_TOTAL_AMOUNT ());
215+ assertEq (totalPeriods, vestingParams.TEAM_TOTAL_PERIODS ());
216+ assertEq (tgePortions, vestingParams.TEAM_TGE_PORTION ());
217+ assertEq (vestingStartMonth, vestingParams.TEAM_VESTING_START_MONTH ());
218+ assertEq (vestingPortion, vestingParams.TEAM_VESTING_PORTION ());
219+ }
220+
221+ function test_getVestingParams_LIQUIDITY () external view {
222+ (
223+ uint256 totalAmount ,
224+ uint256 totalPeriods ,
225+ uint256 tgePortions ,
226+ uint256 vestingStartMonth ,
227+ uint256 vestingPortion
228+ ) = vestingParams.getVestingParams (VestingType.LIQUIDITY);
229+
230+ assertEq (totalAmount, vestingParams.LIQUIDITY_TOTAL_AMOUNT ());
231+ assertEq (totalPeriods, vestingParams.LIQUIDITY_TOTAL_PERIODS ());
232+ assertEq (tgePortions, vestingParams.LIQUIDITY_TGE_PORTION ());
233+ assertEq (vestingStartMonth, vestingParams.LIQUIDITY_VESTING_START_MONTH ());
234+ assertEq (vestingPortion, vestingParams.LIQUIDITY_VESTING_PORTION ());
235+ }
236+
237+ function test_getVestingParams_revertIfInvalidVestingType (uint8 invalidVestingType ) external {
238+ vm.assume (invalidVestingType > uint8 (type (VestingType).max));
239+
240+ (bool success ,) = address (vestingParams).call (
241+ abi.encodeWithSignature ("getVestingParams(uint8) " , invalidVestingType)
242+ );
243+
244+ assertFalse (success);
245+ }
246+
247+ // endregion
248+
249+ function _generateBeneficiaries () private returns (Beneficiary[] memory teamBeneficiaries , Beneficiary[] memory liquidityBeneficiaries ) {
250+ teamBeneficiary1 = makeAddr ("teamBeneficiary1 " );
251+ teamBeneficiary2 = makeAddr ("teamBeneficiary2 " );
252+ liquidityBeneficiary = makeAddr ("liquidityBeneficiary " );
253+
254+ teamBeneficiaries = new Beneficiary [](2 );
255+ teamBeneficiaries[0 ] = Beneficiary ({
256+ account: teamBeneficiary1,
257+ amount: 60_000_000e18
258+ });
259+ teamBeneficiaries[1 ] = Beneficiary ({
260+ account: teamBeneficiary2,
261+ amount: 40_000_000e18
262+ });
263+
264+ liquidityBeneficiaries = new Beneficiary [](1 );
265+ liquidityBeneficiaries[0 ] = Beneficiary ({
266+ account: liquidityBeneficiary,
267+ amount: 287_500_000e18
268+ });
269+ }
270+
271+ }
0 commit comments