Skip to content

Commit 3a2a311

Browse files
committed
test: vesting params
1 parent c7c6562 commit 3a2a311

File tree

3 files changed

+279
-14
lines changed

3 files changed

+279
-14
lines changed

src/tokenDistribution/vesting/VestingParams.sol

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@ contract VestingParams is IVestingParams {
2727
Beneficiary[] memory teamBeneficiaries,
2828
Beneficiary[] memory liquidityBeneficiaries
2929
) {
30-
if (
31-
teamBeneficiaries.length == 0
32-
|| liquidityBeneficiaries.length == 0
33-
) {
34-
revert ZeroBeneficiaries();
35-
}
36-
3730
// TODO: протестировать сколько можно запихать бенефициаров
3831
_validateAndStoreBeneficiaries(VestingType.TEAM, teamBeneficiaries, TEAM_TOTAL_AMOUNT);
3932
_validateAndStoreBeneficiaries(VestingType.LIQUIDITY, liquidityBeneficiaries, LIQUIDITY_TOTAL_AMOUNT);
@@ -71,7 +64,8 @@ contract VestingParams is IVestingParams {
7164
}
7265

7366
schedule = Schedule({
74-
startTime: block.timestamp,
67+
// TODO: подумать на тем, как упростить время
68+
startTime: block.timestamp, // Start time is vesting creation time
7569
periods: periods
7670
});
7771
}
@@ -114,7 +108,8 @@ contract VestingParams is IVestingParams {
114108
TEAM_VESTING_PORTION
115109
);
116110
}
117-
else if (vestingType == VestingType.LIQUIDITY) {
111+
112+
if (vestingType == VestingType.LIQUIDITY) {
118113
return (
119114
LIQUIDITY_TOTAL_AMOUNT,
120115
LIQUIDITY_TOTAL_PERIODS,
@@ -123,18 +118,18 @@ contract VestingParams is IVestingParams {
123118
LIQUIDITY_VESTING_PORTION
124119
);
125120
}
126-
else {
127-
revert InvalidVestingType(vestingType);
128-
}
129121
}
130122

131123
function _validateAndStoreBeneficiaries(
132124
VestingType vestingType,
133125
Beneficiary[] memory beneficiaries,
134126
uint256 expectedTotalAmount
135127
) internal virtual {
136-
uint256 totalAmount;
128+
if (beneficiaries.length == 0) {
129+
revert ZeroBeneficiaries();
130+
}
137131

132+
uint256 totalAmount;
138133
for (uint256 i = 0; i < beneficiaries.length; i++) {
139134
Beneficiary memory beneficiary = beneficiaries[i];
140135

src/tokenDistribution/vesting/interfaces/IVestingParams.sol

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ interface IVestingParams {
88
error ZeroAddress();
99
error ZeroAmount();
1010
error IncorrectBeneficiaryAmounts();
11-
error InvalidVestingType(VestingType vestingType);
1211

1312
function getSchedule(VestingType vestingType) external view returns (Schedule memory schedule);
1413
function getBeneficiaries(VestingType vestingType) external view returns (Beneficiary[] memory);
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
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

Comments
 (0)